packages feed

blanks 0.4.0 → 0.4.1

raw patch · 10 files changed

+63/−38 lines, 10 filesdep +deepseqPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: deepseq

API changes (from Hackage documentation)

+ Blanks.LocScope: instance (Control.DeepSeq.NFData l, Control.DeepSeq.NFData n, Control.DeepSeq.NFData a, Control.DeepSeq.NFData (f (Blanks.LocScope.LocScope l n f a))) => Control.DeepSeq.NFData (Blanks.LocScope.LocScope l n f a)
+ Blanks.Located: instance (Control.DeepSeq.NFData l, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Blanks.Located.Located l a)
+ Blanks.Located: instance GHC.Generics.Generic (Blanks.Located.Located l a)
+ Blanks.Name: instance (Control.DeepSeq.NFData n, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Blanks.Name.Name n a)
+ Blanks.Name: instance GHC.Generics.Generic (Blanks.Name.Name n a)
+ Blanks.Scope: instance (Control.DeepSeq.NFData n, Control.DeepSeq.NFData a, Control.DeepSeq.NFData (f (Blanks.Scope.Scope n f a))) => Control.DeepSeq.NFData (Blanks.Scope.Scope n f a)
+ Blanks.ScopeW: instance Control.DeepSeq.NFData (t (Blanks.UnderScope.UnderScope n f (g a) a)) => Control.DeepSeq.NFData (Blanks.ScopeW.ScopeW t n f g a)
+ Blanks.UnderScope: instance (Control.DeepSeq.NFData a, Control.DeepSeq.NFData n, Control.DeepSeq.NFData e, Control.DeepSeq.NFData (f e)) => Control.DeepSeq.NFData (Blanks.UnderScope.UnderScope n f e a)
+ Blanks.UnderScope: instance (Control.DeepSeq.NFData n, Control.DeepSeq.NFData e) => Control.DeepSeq.NFData (Blanks.UnderScope.BinderScope n e)
+ Blanks.UnderScope: instance Control.DeepSeq.NFData (f e) => Control.DeepSeq.NFData (Blanks.UnderScope.EmbedScope f e)
+ Blanks.UnderScope: instance Control.DeepSeq.NFData Blanks.UnderScope.BoundScope
+ Blanks.UnderScope: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Blanks.UnderScope.FreeScope a)
+ Blanks.UnderScope: instance GHC.Generics.Generic (Blanks.UnderScope.BinderScope n e)
+ Blanks.UnderScope: instance GHC.Generics.Generic (Blanks.UnderScope.UnderScope n f e a)
- Blanks.Name: Name :: n -> a -> Name n a
+ Blanks.Name: Name :: !n -> !a -> Name n a
- Blanks.Name: [_nameKey] :: Name n a -> n
+ Blanks.Name: [_nameKey] :: Name n a -> !n
- Blanks.Name: [_nameValue] :: Name n a -> a
+ Blanks.Name: [_nameValue] :: Name n a -> !a

Files

blanks.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: dce6fa2995f08e5b1615eab81bbbbb7339ba49c1db0902125b8495fc24c84bd1+-- hash: f04965a3798127c433ad644602e9f2d305aadbcc482644902f31342e2390729c  name:           blanks-version:        0.4.0+version:        0.4.1 synopsis:       Fill-in-the-blanks - A library factoring out substitution from ASTs description:    Please see the README on GitHub at <https://github.com/ejconlon/blanks#readme> category:       Language@@ -42,12 +42,13 @@       Paths_blanks   hs-source-dirs:       src-  default-extensions: BangPatterns ConstraintKinds DeriveFunctor DeriveFoldable DeriveGeneric DeriveTraversable FlexibleContexts FlexibleInstances FunctionalDependencies GeneralizedNewtypeDeriving KindSignatures MultiParamTypeClasses PatternSynonyms Rank2Types TypeFamilies+  default-extensions: BangPatterns ConstraintKinds DeriveFunctor DeriveFoldable DeriveGeneric DeriveTraversable DerivingStrategies FlexibleContexts FlexibleInstances FunctionalDependencies GeneralizedNewtypeDeriving KindSignatures MultiParamTypeClasses PatternSynonyms Rank2Types TypeFamilies   ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -fno-warn-unused-top-binds   build-depends:       adjunctions >=4.4 && <5     , base >=4.12 && <5     , containers >=0.6 && <1+    , deepseq >=1.4 && <2     , distributive >=0.6 && <1     , mtl >=2.2 && <3   default-language: Haskell2010@@ -63,13 +64,14 @@       Paths_blanks   hs-source-dirs:       test-  default-extensions: BangPatterns ConstraintKinds DeriveFunctor DeriveFoldable DeriveGeneric DeriveTraversable FlexibleContexts FlexibleInstances FunctionalDependencies GeneralizedNewtypeDeriving KindSignatures MultiParamTypeClasses PatternSynonyms Rank2Types TypeFamilies+  default-extensions: BangPatterns ConstraintKinds DeriveFunctor DeriveFoldable DeriveGeneric DeriveTraversable DerivingStrategies FlexibleContexts FlexibleInstances FunctionalDependencies GeneralizedNewtypeDeriving KindSignatures MultiParamTypeClasses PatternSynonyms Rank2Types TypeFamilies   ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints -fno-warn-unused-top-binds -threaded -rtsopts -with-rtsopts=-N   build-depends:       adjunctions >=4.4 && <5     , base >=4.12 && <5     , blanks     , containers >=0.6 && <1+    , deepseq >=1.4 && <2     , distributive >=0.6 && <1     , megaparsec     , mtl >=2.2 && <3
src/Blanks.hs view
@@ -1,20 +1,4 @@--- | Fill-in-the-blanks - A library factoring out substitution from ASTs.------ It's a pain to track de Bruijn indices yourself to implement capture-avoiding subsititution,--- so this library provides some wrappers that help. One of the best libraries for this is--- <https://hackage.haskell.org/package/bound bound>, which uses a clever representation to make--- these operations safe and fast. The tradeoff is that you have to define a 'Monad' instance--- for your expression functor, which in practice can be tricky. (It's even trickier to derive--- 'Eq' and 'Show'!)------ This library takes the simpler, slower, and rather "succ-y" free-monad-ish approach,--- but with a twist. It expects you to rewrite all name-binding constructors in your expression--- as annotations on a single "binder" constructor. This allows you to use the provided 'Scope'--- type (or a variant) as a wrapper around your expression functor, which is only required to--- implement 'Functor'. This representation is less safe (since you can inspect and manipulate--- bound variables), but if you stick to the provided combinators, things will work out fine.------ You'll get most of what you want by just importing this module unqualified.+-- | You'll get most of what you want by just importing this module unqualified. -- See the 'Blanks' class definition and related methods to manipulate variables and abstractions. -- See 'Scope' for the basic wrapper and 'LocScope' for a wrapper with annotations you can use -- for source locations and the like. See the test suite for examples.
src/Blanks/LocScope.hs view
@@ -17,6 +17,7 @@ import Blanks.ScopeW (ScopeW (..)) import Blanks.UnderScope (pattern UnderScopeBinder, pattern UnderScopeBound, pattern UnderScopeEmbed,                           pattern UnderScopeFree)+import Control.DeepSeq (NFData (..)) import Control.Monad (ap) import Control.Monad.Identity (Identity (..)) import Control.Monad.Writer (MonadWriter (..))@@ -26,7 +27,7 @@ -- and inspection. newtype LocScope l n f a = LocScope   { unLocScope :: ScopeW (Located l) n f (LocScope l n f) a-  } deriving (Functor, Foldable, Traversable)+  } deriving stock (Functor, Foldable, Traversable)  type instance BlankLeft (LocScope l n f) = Located l type instance BlankRight (LocScope l n f) = Colocated l@@ -35,6 +36,9 @@  instance Functor f => Blank (LocScope l n f) instance NatNewtype (ScopeW (Located l) n f (LocScope l n f)) (LocScope l n f)++instance (NFData l, NFData n, NFData a, NFData (f (LocScope l n f a))) => NFData (LocScope l n f a) where+  rnf = rnf . unLocScope  pattern LocScopeBound :: l -> Int -> LocScope l n f a pattern LocScopeBound l b = LocScope (ScopeW (Located l (UnderScopeBound b)))
src/Blanks/Located.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE UndecidableInstances #-}  module Blanks.Located@@ -8,12 +9,14 @@   , runColocated   ) where +import Control.DeepSeq (NFData) import Control.Monad (ap) import Control.Monad.Reader (MonadReader, Reader, ReaderT (..), ask, reader, runReader) import Control.Monad.Writer (MonadWriter (..)) import Data.Distributive (Distributive (..)) import Data.Functor.Adjunction (Adjunction (..)) import Data.Functor.Rep (Representable)+import GHC.Generics (Generic)  -- | This is basically the 'Env' comonad, but with the env strict. -- It's also basically the 'Writer' monad in certain contexts.@@ -21,12 +24,13 @@ data Located l a = Located   { _locatedLoc :: !l   , _locatedVal :: a-  } deriving (Eq, Show, Functor, Foldable, Traversable)+  } deriving stock (Eq, Show, Functor, Foldable, Traversable, Generic)+    deriving anyclass (NFData)  -- | Because we defined a unique left adjoint, we have to define the unique right. newtype Colocated l a = Colocated   { unColocated :: Reader l a-  } deriving (Functor, Applicative, Monad, MonadReader l, Representable)+  } deriving newtype (Functor, Applicative, Monad, MonadReader l, Representable)  colocated :: (l -> a) -> Colocated l a colocated f = Colocated (reader f)
src/Blanks/Name.hs view
@@ -1,18 +1,24 @@+{-# LANGUAGE DeriveAnyClass #-}+ module Blanks.Name   ( Name (..)   , NameOnly   , pattern NameOnly   ) where +import Control.DeepSeq (NFData)+import GHC.Generics (Generic)+ -- | 'Name' is compared on value only, allowing you to define and use -- things like 'NameOnly' in your 'BlankInfo' values to make alpha-equivalent -- terms structurally ('Eq') equivalent. data Name n a =   Name-    { _nameKey :: n-    , _nameValue :: a+    { _nameKey :: !n+    , _nameValue :: !a     }-  deriving (Show, Functor, Foldable, Traversable)+  deriving stock (Show, Functor, Foldable, Traversable, Generic)+  deriving anyclass (NFData)  instance Eq a => Eq (Name n a) where   Name _ x == Name _ y = x == y
src/Blanks/Scope.hs view
@@ -13,6 +13,7 @@ import Blanks.ScopeW (ScopeW (..)) import Blanks.UnderScope (pattern UnderScopeBinder, pattern UnderScopeBound, pattern UnderScopeEmbed,                           pattern UnderScopeFree)+import Control.DeepSeq (NFData (..)) import Control.Monad (ap) import Control.Monad.Identity (Identity (..)) @@ -21,7 +22,7 @@ -- and inspection. newtype Scope n f a = Scope   { unScope :: ScopeW Identity n f (Scope n f) a-  } deriving (Functor, Foldable, Traversable)+  } deriving stock (Functor, Foldable, Traversable)  type instance BlankLeft (Scope n f) = Identity type instance BlankRight (Scope n f) = Identity@@ -30,6 +31,9 @@  instance Functor f => Blank (Scope n f) instance NatNewtype (ScopeW Identity n f (Scope n f)) (Scope n f)++instance (NFData n, NFData a, NFData (f (Scope n f a))) => NFData (Scope n f a) where+  rnf = rnf . unScope  pattern ScopeBound :: Int -> Scope n f a pattern ScopeBound b = Scope (ScopeW (Identity (UnderScopeBound b)))
src/Blanks/ScopeW.hs view
@@ -26,6 +26,7 @@ import Blanks.Sub (SubError (..)) import Blanks.UnderScope (UnderScope, pattern UnderScopeBinder, pattern UnderScopeBound, pattern UnderScopeEmbed,                           UnderScopeFold, pattern UnderScopeFree, underScopeFold, underScopeShift)+import Control.DeepSeq (NFData (..)) import Data.Bifoldable (bifoldr) import Data.Bifunctor (bimap, first) import Data.Bitraversable (bitraverse)@@ -39,6 +40,9 @@ newtype ScopeW t n f g a = ScopeW   { unScopeW :: t (UnderScope n f (g a) a)   }++instance NFData (t (UnderScope n f (g a) a) )=> NFData (ScopeW t n f g a) where+  rnf = rnf . unScopeW  instance Eq (t (UnderScope n f (g a) a)) => Eq (ScopeW t n f g a) where   ScopeW tu == ScopeW tv = tu == tv
src/Blanks/UnderScope.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+ -- | Internals. You will probably never need these. module Blanks.UnderScope   ( BinderScope (..)@@ -14,21 +16,24 @@   , underScopeShift   ) where +import Control.DeepSeq (NFData) import Data.Bifoldable (Bifoldable (..)) import Data.Bifunctor (Bifunctor (..)) import Data.Bitraversable (Bitraversable (..))+import GHC.Generics (Generic)  newtype BoundScope =   BoundScope     { unBoundScope :: Int     }-  deriving (Eq, Show)+  deriving newtype (Eq, Show, NFData)  newtype FreeScope a =   FreeScope     { unFreeScope :: a     }-  deriving (Eq, Show, Functor, Foldable, Traversable)+  deriving stock (Eq, Show, Functor, Foldable, Traversable)+  deriving newtype (NFData)  data BinderScope n e =   BinderScope@@ -36,20 +41,22 @@     , binderScopeInfo :: !n     , binderScopeBody :: e     }-  deriving (Eq, Show, Functor, Foldable, Traversable)+  deriving stock (Eq, Show, Functor, Foldable, Traversable, Generic)+  deriving anyclass (NFData)  newtype EmbedScope f e =   EmbedScope     { unEmbedScope :: f e     }-  deriving (Eq, Show, Functor)+  deriving newtype (Eq, Show, Functor, NFData)  data UnderScope n f e a   = UnderBoundScope !BoundScope   | UnderFreeScope !(FreeScope a)   | UnderBinderScope !(BinderScope n e)   | UnderEmbedScope !(EmbedScope f e)-  deriving (Eq, Show, Functor)+  deriving stock (Eq, Show, Functor, Generic)+  deriving anyclass (NFData)  pattern UnderScopeBound :: Int -> UnderScope n f e a pattern UnderScopeBound i = UnderBoundScope (BoundScope i)
test/Test/Blanks/LocScopeTest.hs view
@@ -1,13 +1,16 @@+{-# LANGUAGE DeriveAnyClass #-}+ module Test.Blanks.LocScopeTest where  import Blanks-import Data.String (IsString)+import Control.DeepSeq (NFData, force)+import GHC.Generics (Generic) import Test.Blanks.Parsing import Test.Tasty import Test.Tasty.HUnit  -- A newtype indicating an identifier in our language-newtype Ident = Ident { unIdent :: String } deriving (Eq, Show, Ord, IsString)+newtype Ident = Ident { unIdent :: String } deriving newtype (Eq, Show, Ord, NFData)  -- The type of concrete expressions, labeled with source location data CExp l =@@ -45,7 +48,8 @@   | ExpAdd a a   | ExpIf a a a   | ExpIsZero a-  deriving (Eq, Show, Functor, Foldable, Traversable)+  deriving stock (Eq, Show, Functor, Foldable, Traversable, Generic)+  deriving anyclass (NFData)  -- A nameless equivalent to 'CExp' type ExpScope l = LocScope l (NameOnly Ident) Exp Ident@@ -125,7 +129,8 @@ testSingle :: TestName -> String -> ExpSimpleScope -> TestTree testSingle name input expected = testCase name $ do   namedExp <- runParserIO cexpParser input-  let namelessExp = nameless namedExp+  -- Force here just to test that we can+  let namelessExp = force (nameless namedExp)   cexpLoc namedExp @?= locScopeLocation namelessExp   let actual = locScopeForget namelessExp   expected @?= actual
test/Test/Blanks/Parsing.hs view
@@ -1,8 +1,12 @@+{-# LANGUAGE DeriveAnyClass #-}+ module Test.Blanks.Parsing where  import Control.Applicative (Alternative (..))+import Control.DeepSeq (NFData) import Control.Exception (throwIO) import Data.Void (Void)+import GHC.Generics (Generic) import qualified Text.Megaparsec as MP import qualified Text.Megaparsec.Char as MPC import qualified Text.Megaparsec.Char.Lexer as MPCL@@ -23,7 +27,8 @@   , _ssStartColumn :: !MP.Pos   , _ssEndLine :: !MP.Pos   , _ssEndColumn :: !MP.Pos-  } deriving (Eq, Show, Ord)+  } deriving stock (Eq, Show, Ord, Generic)+    deriving anyclass (NFData)  mkSourceSpan :: MP.SourcePos -> MP.SourcePos -> SourceSpan mkSourceSpan (MP.SourcePos n sl sc) (MP.SourcePos _ el ec) = SourceSpan n sl sc el ec