bound 0.8.1 → 0.9
raw patch · 6 files changed
+62/−36 lines, 6 files
Files
- CHANGELOG.markdown +4/−0
- README.markdown +31/−22
- bound.cabal +2/−2
- src/Bound/Class.hs +11/−4
- src/Bound/Scope.hs +11/−5
- src/Bound/Scope/Simple.hs +3/−3
CHANGELOG.markdown view
@@ -1,3 +1,7 @@+0.9+---+* Added the missing instance for `Applicative (Scope b f)`+ 0.8.1 ----- * SafeHaskell support
README.markdown view
@@ -12,33 +12,42 @@ See [the documentation](http://hackage.haskell.org/package/bound) on hackage for more information, but here is an example: - import Bound- import Prelude.Extras+```haskell+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveTraversable #-}+import Bound+import Prelude.Extras+import Control.Applicative+import Control.Monad+import Data.Foldable+import Data.Traversable - infixl 9 :@- data Exp a = V a | Exp a :@ Exp a | Lam (Scope () Exp a)- deriving (Eq,Ord,Show,Read,Functor,Foldable,Traversable)+infixl 9 :@+data Exp a = V a | Exp a :@ Exp a | Lam (Scope () Exp a)+ deriving (Eq,Ord,Show,Read,Functor,Foldable,Traversable) - instance Eq1 Exp- instance Ord1 Exp- instance Show1 Exp- instance Read1 Exp- instance Applicative Exp where pure = V; (<*>) = ap+instance Eq1 Exp+instance Ord1 Exp+instance Show1 Exp+instance Read1 Exp+instance Applicative Exp where pure = V; (<*>) = ap - instance Monad Exp where- return = V- V a >>= f = f a- (x :@ y) >>= f = (x >>= f) :@ (y >>= f)- Lam e >>= f = Lam (e >>>= f)+instance Monad Exp where+ return = V+ V a >>= f = f a+ (x :@ y) >>= f = (x >>= f) :@ (y >>= f)+ Lam e >>= f = Lam (e >>>= f) - lam :: Eq a => a -> Exp a -> Exp a- lam v b = Lam (abstract1 v b)+lam :: Eq a => a -> Exp a -> Exp a+lam v b = Lam (abstract1 v b) - whnf :: Exp a -> Exp a- whnf (f :@ a) = case whnf f of- Lam b -> whnf (instantiate1 a b)- f' -> f' :@ a- whnf e = e+whnf :: Exp a -> Exp a+whnf (f :@ a) = case whnf f of+ Lam b -> whnf (instantiate1 a b)+ f' -> f' :@ a+whnf e = e+``` There are longer examples in the [examples/ folder](https://github.com/ekmett/bound/tree/master/examples).
bound.cabal view
@@ -1,6 +1,6 @@ name: bound category: Language, Compilers/Interpreters-version: 0.8.1+version: 0.9 license: BSD3 cabal-version: >= 1.9.2 license-file: LICENSE@@ -9,7 +9,7 @@ stability: experimental homepage: http://github.com/ekmett/bound/ bug-reports: http://github.com/ekmett/bound/issues-copyright: Copyright (C) 2012 Edward A. Kmett+copyright: Copyright (C) 2012-2013 Edward A. Kmett synopsis: Making de Bruijn Succ Less build-type: Custom description:
src/Bound/Class.hs view
@@ -25,11 +25,18 @@ infixl 1 >>>= --- | Instances of 'Bound' may or may not be monad transformers.+-- | Instances of 'Bound' generate left modules over monads.+-- +-- This means they should satisfy the following laws: ----- If they are, then @m '>>>=' f ≡ m '>>=' 'lift' '.' f@ is required to hold, and is--- in fact the default definition. If it is not a 'MonadTrans' instance, then--- you have greater flexibility in how to implement this class.+-- > m >>>= return ≡ m+-- > m >>>= (λ x → k x >>= h) ≡ (m >>>= k) >>>= h+--+-- This guarantees that a typical Monad instance for an expression type+-- where Bound instances appear will satisfy the Monad laws (see doc/BoundLaws.hs).+--+-- If instances of Bound are monad transformers, then @m '>>>=' f ≡ m '>>=' 'lift' '.' f@+-- implies the above laws, and is in fact the default definition. -- -- This is useful for types like expression lists, case alternatives, -- schemas, etc. that may not be expressions in their own right, but often
src/Bound/Scope.hs view
@@ -4,7 +4,7 @@ #endif ----------------------------------------------------------------------------- -- |--- Copyright : (C) 2012 Edward Kmett+-- Copyright : (C) 2012-2013 Edward Kmett -- License : BSD-style (see the file LICENSE) -- -- Maintainer : Edward Kmett <ekmett@gmail.com>@@ -111,6 +111,12 @@ traverse f (Scope a) = Scope <$> traverse (traverse (traverse f)) a {-# INLINE traverse #-} +instance (Functor f, Monad f) => Applicative (Scope b f) where+ pure = return+ {-# INLINE pure #-}+ (<*>) = ap+ {-# INLINE (<*>) #-}+ -- | The monad permits substitution on free variables, while preserving -- bound variables instance Monad f => Monad (Scope b f) where@@ -129,21 +135,21 @@ (==) = (==#) {-# INLINE (==) #-} instance (Monad f, Eq b, Eq1 f) => Eq1 (Scope b f) where- a ==# b = liftM Lift2 (fromScope a) ==# liftM Lift2 (fromScope b)+ a ==# b = fromScope a ==# fromScope b {-# INLINE (==#) #-} instance (Monad f, Ord b, Ord1 f, Ord a) => Ord (Scope b f a) where compare = compare1 {-# INLINE compare #-} instance (Monad f, Ord b, Ord1 f) => Ord1 (Scope b f) where- compare1 a b = liftM Lift2 (fromScope a) `compare1` liftM Lift2 (fromScope b)+ compare1 a b = fromScope a `compare1` fromScope b {-# INLINE compare1 #-} instance (Functor f, Show b, Show1 f, Show a) => Show (Scope b f a) where showsPrec = showsPrec1 instance (Functor f, Show b, Show1 f) => Show1 (Scope b f) where showsPrec1 d a = showParen (d > 10) $- showString "Scope " . showsPrec1 11 (fmap (Lift2 . fmap Lift1) (unscope a))+ showString "Scope " . showsPrec1 11 (fmap (fmap Lift1) (unscope a)) instance (Functor f, Read b, Read1 f, Read a) => Read (Scope b f a) where readsPrec = readsPrec1@@ -151,7 +157,7 @@ readsPrec1 d = readParen (d > 10) $ \r -> do ("Scope", r') <- lex r (s, r'') <- readsPrec1 11 r'- return (Scope (fmap (fmap lower1 . lower2) s), r'')+ return (Scope (fmap (fmap lower1) s), r'') instance Bound (Scope b) where Scope m >>>= f = Scope (liftM (fmap (>>= f)) m)
src/Bound/Scope/Simple.hs view
@@ -123,21 +123,21 @@ (==) = (==#) {-# INLINE (==) #-} instance (Functor f, Eq b, Eq1 f) => Eq1 (Scope b f) where- a ==# b = fmap Lift2 (unscope a) ==# fmap Lift2 (unscope b)+ a ==# b = unscope a ==# unscope b {-# INLINE (==#) #-} instance (Functor f, Ord b, Ord1 f, Ord a) => Ord (Scope b f a) where compare = compare1 {-# INLINE compare #-} instance (Functor f, Ord b, Ord1 f) => Ord1 (Scope b f) where- compare1 a b = fmap Lift2 (unscope a) `compare1` fmap Lift2 (unscope b)+ compare1 a b = unscope a `compare1` unscope b {-# INLINE compare1 #-} instance (Functor f, Show b, Show1 f, Show a) => Show (Scope b f a) where showsPrec = showsPrec1 instance (Functor f, Show b, Show1 f) => Show1 (Scope b f) where showsPrec1 d a = showParen (d > 10) $- showString "Scope " . showsPrec1 11 (fmap Lift2 (unscope a))+ showString "Scope " . showsPrec1 11 (unscope a) instance (Functor f, Read b, Read1 f, Read a) => Read (Scope b f a) where readsPrec = readsPrec1