packages feed

operational 0.2.1.3 → 0.2.2.0

raw patch · 2 files changed

+52/−43 lines, 2 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.Monad.Operational: interpretWithMonad :: Monad m => (forall a. instr a -> m a) -> (Program instr b -> m b)

Files

operational.cabal view
@@ -1,5 +1,5 @@ Name:               operational-Version:            0.2.1.3+Version:            0.2.2.0 Synopsis:           Implementation of difficult monads made easy                     with operational semantics. Description:@@ -37,7 +37,8 @@     hs-source-dirs:     src     build-depends:      base == 4.* , mtl >= 1.1 && < 2.2.0     ghc-options:        -Wall-    extensions:         GADTs, UndecidableInstances,+    extensions:         GADTs, Rank2Types, ScopedTypeVariables,+                        UndecidableInstances,                         MultiParamTypeClasses, FlexibleInstances     exposed-modules:    Control.Monad.Operational 
src/Control/Monad/Operational.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE GADTs, UndecidableInstances, MultiParamTypeClasses, FlexibleInstances #-}+{-# LANGUAGE GADTs, Rank2Types, ScopedTypeVariables #-}+{-# LANGUAGE UndecidableInstances, MultiParamTypeClasses, FlexibleInstances #-} -- Search for UndecidableInstances to see why this is needed  module Control.Monad.Operational (@@ -11,6 +12,7 @@     -- * Monad     Program, singleton, ProgramView, view,     -- $example+    interpretWithMonad,          -- * Monad transformer     ProgramT, ProgramViewT(..), viewT,@@ -135,32 +137,43 @@ view :: Program instr a -> ProgramView instr a view = runIdentity . viewT ++-- | Utility function that extends+-- a given interpretation of instructions as monadic actions+-- to an interpration of 'Program's as monadic actions.+--+-- This function can be useful if you are mainly interested in+-- mapping a 'Program' to different standard monads, like the state monad.+-- For implementing a truly custom monad, +-- you should write your interpreter directly with 'view' instead.+interpretWithMonad :: forall instr m b.+    Monad m => (forall a. instr a -> m a) -> (Program instr b -> m b)+interpretWithMonad f = eval . view+    where+    eval :: forall a. ProgramView instr a -> m a+    eval (Return a) = return a+    eval (m :>>= k) = f m >>= interpretWithMonad f . k+ {- $example  /Example usage/  Stack machine from \"The Operational Monad Tutorial\". -@-    data StackInstruction a where-        Push :: Int -> StackInstruction ()-        Pop  :: StackInstruction Int-@--@-    type StackProgram a = Program StackInstruction a-    type Stack b        = [b]-@--@-    interpret :: StackProgram a -> (Stack Int -> a)-    interpret = eval . view-        where-        eval :: ProgramView StackInstruction a -> (Stack Int -> a)-        eval (Push a :>>= is) stack     = interpret (is ()) (a:stack)-        eval (Pop    :>>= is) (a:stack) = interpret (is a ) stack-        eval (Return a)       stack     = a-@+>    data StackInstruction a where+>        Push :: Int -> StackInstruction ()+>        Pop  :: StackInstruction Int+>+>    type StackProgram a = Program StackInstruction a+>    type Stack b        = [b]+>+>    interpret :: StackProgram a -> (Stack Int -> a)+>    interpret = eval . view+>        where+>        eval :: ProgramView StackInstruction a -> (Stack Int -> a)+>        eval (Push a :>>= is) stack     = interpret (is ()) (a:stack)+>        eval (Pop    :>>= is) (a:stack) = interpret (is a ) stack+>        eval (Return a)       stack     = a  Note that since 'ProgramView' is a GADT, the type annotation for @eval@ is mandatory. @@ -249,32 +262,27 @@ liftProgram (m `Bind` k) = liftProgram m `Bind` (liftProgram . k) liftProgram (Instr i)    = Instr i + {- $exampleT  /Example usage/  List monad transformer. -@-    data PlusI m a where-        Zero :: PlusI m a-        Plus :: ListT m a -> ListT m a -> PlusI m a-@--@-    type ListT m a = ProgramT (PlusI m) m a-@--@-    runList :: Monad m => ListT m a -> m [a]-    runList = eval <=< viewT-        where-        eval :: Monad m => ProgramViewT (PlusI m) m a -> m [a]-        eval (Return x)        = return [x]-        eval (Zero     :>>= k) = return []-        eval (Plus m n :>>= k) =-            liftM2 (++) (runList (m >>= k)) (runList (n >>= k))-@+>    data PlusI m a where+>        Zero :: PlusI m a+>        Plus :: ListT m a -> ListT m a -> PlusI m a+>+>    type ListT m a = ProgramT (PlusI m) m a+>+>    runList :: Monad m => ListT m a -> m [a]+>    runList = eval <=< viewT+>        where+>        eval :: Monad m => ProgramViewT (PlusI m) m a -> m [a]+>        eval (Return x)        = return [x]+>        eval (Zero     :>>= k) = return []+>        eval (Plus m n :>>= k) =+>            liftM2 (++) (runList (m >>= k)) (runList (n >>= k))  Note that since 'ProgramView' is a GADT, the type annotation for @eval@ is mandatory.