operational-0.1.0.0: Implement monads by specifying operational semantics.

Control.Monad.Operational

Contents

Description

Implement monads by specifying primitive instructions and their operational semantics.

This package is based on the "The Operational Monad Tutorial", published in Issue 15 of The Monad.Reader http://themonadreader.wordpress.com/.

You are reading the API reference. For more thorough documentation including design and implementation notes as well as a correctness proof, please consult the included doc/Documentation.html.

This API reference includes only basic example code. More intricate examples are available in the doc/examples directory.

Synopsis

Basic usage

type Program instr a = ProgramT instr Identity aSource

The abstract data type 'Program instr a' represents programs.

  • The type constructor instr :: * -> * indexes the primitive instructions.
  • a is the return type of a program.

Program instr is always a monad and automatically obeys the monad laws.

singleton :: instr a -> ProgramT instr m aSource

Program made from a single primitive instruction.

type Prompt instr a = PromptT instr Identity aSource

View type for inspecting the first instruction. It has two constructors Return and :>>=. (For technical reasons, they are documented at PromptT.)

view :: Program instr a -> Prompt instr aSource

View function for inspecting the first instruction.

Example

Stack machine from "The Operational Monad Tutorial".

    data StackInstruction a where
        Push :: Int -> StackInstruction ()
        Pop  :: StackInstruction Int
    type StackProgram a = Program StackInstruction a
    interpret :: StackProgram a -> (Stack Int -> a)
    interpret = eval . view
        where
        eval :: Prompt 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 Prompt is a GADT, the type annotation for eval is mandatory.

Monad transformer

data ProgramT instr m a Source

The abstract data type ProgramT instr m a represents programs.

  • The type constructor instr :: * -> * indexes the primitive instructions.
  • m is the base monad, embedded with lift.
  • a is the return type of a program.

ProgramT instr m is a monad transformer and automatically obey both the monad and the lifting laws.

Instances

MonadTrans (ProgramT instr) 
Monad m => Monad (ProgramT instr m) 
Monad m => Functor (ProgramT instr m) 
Monad m => Applicative (ProgramT instr m) 

data PromptT instr m a whereSource

View type for inspecting the first instruction.

Constructors

Return :: a -> PromptT instr m a 
:>>= :: instr b -> (b -> ProgramT instr m a) -> PromptT instr m a 

viewT :: Monad m => ProgramT instr m a -> m (PromptT instr m a)Source

View function for inspecting the first instruction.

Example

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 => PromptT (PlusI m) m a -> m [a]
        eval (Return x)        = return [x]
        eval (Zero     :>>= g) = return []
        eval (Plus m n :>>= g) =
            liftM2 (++) (runList (m >>= g)) (runList (n >>= g))

Note that since Prompt is a GADT, the type annotation for eval is mandatory.