/usr/share/doc/libghc-operational-doc/html/Control-Monad-Operational.html is in libghc-operational-doc 0.2.3.2-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Control.Monad.Operational</title><link href="ocean.css" rel="stylesheet" type="text/css" title="Ocean" /><script src="haddock-util.js" type="text/javascript"></script><script type="text/javascript">//<![CDATA[
window.onload = function () {pageLoad();setSynopsis("mini_Control-Monad-Operational.html");};
//]]>
</script></head><body><div id="package-header"><ul class="links" id="page-menu"><li><a href="src/Control-Monad-Operational.html">Source</a></li><li><a href="index.html">Contents</a></li><li><a href="doc-index.html">Index</a></li></ul><p class="caption">operational-0.2.3.2: Implementation of difficult monads made easy
with operational semantics.</p></div><div id="content"><div id="module-header"><table class="info"><tr><th>Safe Haskell</th><td>Safe</td></tr><tr><th>Language</th><td>Haskell98</td></tr></table><p class="caption">Control.Monad.Operational</p></div><div id="table-of-contents"><p class="caption">Contents</p><ul><li><a href="#g:1">Synopsis</a></li><li><a href="#g:2">Overview</a></li><li><a href="#g:3">Monad</a></li><li><a href="#g:4">Monad transformer</a></li></ul></div><div id="synopsis"><p id="control.syn" class="caption expander" onclick="toggleSection('syn')">Synopsis</p><ul id="section.syn" class="hide" onclick="toggleSection('syn')"><li class="src short"><span class="keyword">type</span> <a href="#t:Program">Program</a> instr = <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Data-Functor-Identity.html#t:Identity">Identity</a></li><li class="src short"><a href="#v:singleton">singleton</a> :: instr a -> <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a</li><li class="src short"><span class="keyword">type</span> <a href="#t:ProgramView">ProgramView</a> instr = <a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Data-Functor-Identity.html#t:Identity">Identity</a></li><li class="src short"><a href="#v:view">view</a> :: <a href="Control-Monad-Operational.html#t:Program">Program</a> instr a -> <a href="Control-Monad-Operational.html#t:ProgramView">ProgramView</a> instr a</li><li class="src short"><a href="#v:interpretWithMonad">interpretWithMonad</a> :: <span class="keyword">forall</span> instr m b. <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => (<span class="keyword">forall</span> a. instr a -> m a) -> <a href="Control-Monad-Operational.html#t:Program">Program</a> instr b -> m b</li><li class="src short"><span class="keyword">data</span> <a href="#t:ProgramT">ProgramT</a> instr m a</li><li class="src short"><span class="keyword">data</span> <a href="#t:ProgramViewT">ProgramViewT</a> instr m a <span class="keyword">where</span><ul class="subs"><li><a href="#v:Return">Return</a> :: a -> <a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr m a</li><li><a href="#v::-62--62--61-">(:>>=)</a> :: instr b -> (b -> <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a) -> <a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr m a</li></ul></li><li class="src short"><a href="#v:viewT">viewT</a> :: <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a -> m (<a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr m a)</li><li class="src short"><a href="#v:liftProgram">liftProgram</a> :: <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => <a href="Control-Monad-Operational.html#t:Program">Program</a> instr a -> <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a</li></ul></div><div id="interface"><h1 id="g:1">Synopsis</h1><div class="doc"><p>To write a monad, use the <code><a href="Control-Monad-Operational.html#t:Program">Program</a></code> type.</p><p>To write a monad transformer, use the <code><a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a></code> type.</p><p>For easier interoperability,
the <code><a href="Control-Monad-Operational.html#t:Program">Program</a></code> type is actually a type synonym
and defined in terms of <code><a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a></code>.</p></div><h1 id="g:2">Overview</h1><div class="doc"><p>The basic idea for implementing monads with this libary
is to think of monads as <em>sequences of primitive instructions</em>.
For instance, imagine that you want to write a web application
with a custom monad that features an instruction</p><pre>askUserInput :: CustomMonad UserInput</pre><p>which sends a form to the remote user and waits for the user
to send back his input</p><p>To implement this monad, you decide that this instruction is
a primitive, i.e. should not be implemented in terms of other,
more basic instructions.
Once you have chosen your primitives, collect them in a data type</p><pre>data CustomMonadInstruction a where
AskUserInput :: CustomMonadInstruction UserInput
</pre><p>Then, obtain your custom monad simply by applying the <code><a href="Control-Monad-Operational.html#t:Program">Program</a></code>
type constructor</p><pre>type CustomMonad a = Program CustomMonadInstruction a</pre><p>The library makes sure that it is an instance of the <code><a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a></code> class
and fulfills all the required laws.</p><p>Essentially, the monad you now obtained is just a
fancy list of primitive instructions.
In particular, you can pattern match on the first element of this "list".
This is how you implement an <code>interpret</code> or <code>run</code> function for your monad.
Note that pattern matching is done using the <code><a href="Control-Monad-Operational.html#v:view">view</a></code> function</p><pre>runCustomMonad :: CustomMonad a -> IO a
runCustomMonad m = case view m of
Return a -> return a -- done, return the result
AskUserInput :>>= k -> do
b <- waitForUserInput -- wait for external user input
runCustomMonad (k b) -- proceed with next instruction
</pre><p>The point is that you can now proceed in any way you like:
you can wait for the user to return input as shown,
or you store the continuation <code>k</code> and retrieve it when
your web application receives another HTTP request,
or you can keep a log of all user inputs on the client side an replay them,
and so on. Moreover, you can implement different <code>run</code> functions
for one and the same custom monad, which is useful for testing.
Also note that the result type of the <code>run</code> function does not need to
be a monad at all.</p><p>In essence, your custom monad allows you to express
your web application as a simple imperative program,
while the underlying implementation can freely map this to
an event-drived model or some other control flow architecture
of your choice.</p><p>The possibilities are endless.
More usage examples can be found here:
<a href="https://github.com/HeinrichApfelmus/operational/tree/master/doc/examples#readme">https://github.com/HeinrichApfelmus/operational/tree/master/doc/examples#readme</a></p></div><h1 id="g:3">Monad</h1><div class="top"><p class="src"><span class="keyword">type</span> <a name="t:Program" class="def">Program</a> instr = <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Data-Functor-Identity.html#t:Identity">Identity</a> <a href="src/Control-Monad-Operational.html#Program" class="link">Source</a></p><div class="doc"><p>The abstract data type <code><code><a href="Control-Monad-Operational.html#t:Program">Program</a></code> instr a</code> represents programs,
i.e. sequences of primitive instructions.</p><ul><li>The <em>primitive instructions</em> are given by the type constructor <code>instr :: * -> *</code>.</li><li><code>a</code> is the return type of a program.</li></ul><p><code><code><a href="Control-Monad-Operational.html#t:Program">Program</a></code> instr</code> is always a monad and
automatically obeys the monad laws.</p></div></div><div class="top"><p class="src"><a name="v:singleton" class="def">singleton</a> :: instr a -> <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a <a href="src/Control-Monad-Operational.html#singleton" class="link">Source</a></p><div class="doc"><p>Program made from a single primitive instruction.</p></div></div><div class="top"><p class="src"><span class="keyword">type</span> <a name="t:ProgramView" class="def">ProgramView</a> instr = <a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Data-Functor-Identity.html#t:Identity">Identity</a> <a href="src/Control-Monad-Operational.html#ProgramView" class="link">Source</a></p><div class="doc"><p>View type for inspecting the first instruction.
It has two constructors <code><a href="Control-Monad-Operational.html#v:Return">Return</a></code> and <code>:>>=</code>.
(For technical reasons, they are documented at <code><a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a></code>.)</p></div></div><div class="top"><p class="src"><a name="v:view" class="def">view</a> :: <a href="Control-Monad-Operational.html#t:Program">Program</a> instr a -> <a href="Control-Monad-Operational.html#t:ProgramView">ProgramView</a> instr a <a href="src/Control-Monad-Operational.html#view" class="link">Source</a></p><div class="doc"><p>View function for inspecting the first instruction.</p></div></div><div class="doc"><p><em>Example usage</em></p><p>Stack machine from "The Operational Monad Tutorial".</p><pre> 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</pre><p>Note that since <code><a href="Control-Monad-Operational.html#t:ProgramView">ProgramView</a></code> is a GADT, the type annotation for <code>eval</code> is mandatory.</p></div><div class="top"><p class="src"><a name="v:interpretWithMonad" class="def">interpretWithMonad</a> :: <span class="keyword">forall</span> instr m b. <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => (<span class="keyword">forall</span> a. instr a -> m a) -> <a href="Control-Monad-Operational.html#t:Program">Program</a> instr b -> m b <a href="src/Control-Monad-Operational.html#interpretWithMonad" class="link">Source</a></p><div class="doc"><p>Utility function that extends
a given interpretation of instructions as monadic actions
to an interpration of <code><a href="Control-Monad-Operational.html#t:Program">Program</a></code>s as monadic actions.</p><p>This function can be useful if you are mainly interested in
mapping a <code><a href="Control-Monad-Operational.html#t:Program">Program</a></code> to different standard monads, like the state monad.
For implementing a truly custom monad,
you should write your interpreter directly with <code><a href="Control-Monad-Operational.html#v:view">view</a></code> instead.</p></div></div><h1 id="g:4">Monad transformer</h1><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:ProgramT" class="def">ProgramT</a> instr m a <a href="src/Control-Monad-Operational.html#ProgramT" class="link">Source</a></p><div class="doc"><p>The abstract data type <code><code><a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a></code> instr m a</code> represents programs
over a base monad <code>m</code>,
i.e. sequences of primitive instructions and actions from the base monad.</p><ul><li>The <em>primitive instructions</em> are given by the type constructor <code>instr :: * -> *</code>.</li><li><code>m</code> is the base monad, embedded with <code><a href="file:///usr/share/doc/ghc-doc/html/libraries/transformers-0.4.2.0/Control-Monad-Trans-Class.html#v:lift">lift</a></code>.</li><li><code>a</code> is the return type of a program.</li></ul><p><code><code><a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a></code> instr m</code> is a monad transformer and
automatically obeys both the monad and the lifting laws.</p></div><div class="subs instances"><p id="control.i:ProgramT" class="caption collapser" onclick="toggleSection('i:ProgramT')">Instances</p><div id="section.i:ProgramT" class="show"><table><tr><td class="src clearfix"><span class="inst-left"><a href="file:///usr/share/doc/libghc-mtl-doc/html/Control-Monad-Reader-Class.html#t:MonadReader">MonadReader</a> r m => <a href="file:///usr/share/doc/libghc-mtl-doc/html/Control-Monad-Reader-Class.html#t:MonadReader">MonadReader</a> r (<a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m)</span> <a href="src/Control-Monad-Operational.html#line-309" class="link">Source</a></td><td class="doc empty"> </td></tr><tr><td class="src clearfix"><span class="inst-left"><a href="file:///usr/share/doc/libghc-mtl-doc/html/Control-Monad-State-Class.html#t:MonadState">MonadState</a> s m => <a href="file:///usr/share/doc/libghc-mtl-doc/html/Control-Monad-State-Class.html#t:MonadState">MonadState</a> s (<a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m)</span> <a href="src/Control-Monad-Operational.html#line-302" class="link">Source</a></td><td class="doc empty"> </td></tr><tr><td class="src clearfix"><span class="inst-left"><a href="file:///usr/share/doc/ghc-doc/html/libraries/transformers-0.4.2.0/Control-Monad-Trans-Class.html#t:MonadTrans">MonadTrans</a> (<a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr)</span> <a href="src/Control-Monad-Operational.html#line-209" class="link">Source</a></td><td class="doc empty"> </td></tr><tr><td class="src clearfix"><span class="inst-left"><a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> (<a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m)</span> <a href="src/Control-Monad-Operational.html#line-205" class="link">Source</a></td><td class="doc empty"> </td></tr><tr><td class="src clearfix"><span class="inst-left"><a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Data-Functor.html#t:Functor">Functor</a> (<a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m)</span> <a href="src/Control-Monad-Operational.html#line-212" class="link">Source</a></td><td class="doc empty"> </td></tr><tr><td class="src clearfix"><span class="inst-left"><a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Applicative.html#t:Applicative">Applicative</a> (<a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m)</span> <a href="src/Control-Monad-Operational.html#line-215" class="link">Source</a></td><td class="doc empty"> </td></tr><tr><td class="src clearfix"><span class="inst-left"><a href="file:///usr/share/doc/ghc-doc/html/libraries/transformers-0.4.2.0/Control-Monad-IO-Class.html#t:MonadIO">MonadIO</a> m => <a href="file:///usr/share/doc/ghc-doc/html/libraries/transformers-0.4.2.0/Control-Monad-IO-Class.html#t:MonadIO">MonadIO</a> (<a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m)</span> <a href="src/Control-Monad-Operational.html#line-306" class="link">Source</a></td><td class="doc empty"> </td></tr></table></div></div></div><div class="top"><p class="src"><span class="keyword">data</span> <a name="t:ProgramViewT" class="def">ProgramViewT</a> instr m a <span class="keyword">where</span> <a href="src/Control-Monad-Operational.html#ProgramViewT" class="link">Source</a></p><div class="doc"><p>View type for inspecting the first instruction.
This is very similar to pattern matching on lists.</p><ul><li>The case <code>(Return a)</code> means that the program contains no instructions
and just returns the result <code>a</code>.</li><li>The case <code>(someInstruction :>>= k)</code> means that the first instruction
is <code>someInstruction</code> and the remaining program is given by the function <code>k</code>.</li></ul></div><div class="subs constructors"><p class="caption">Constructors</p><table><tr><td class="src"><a name="v:Return" class="def">Return</a> :: a -> <a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr m a</td><td class="doc empty"> </td></tr><tr><td class="src"><a name="v::-62--62--61-" class="def">(:>>=)</a> :: instr b -> (b -> <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a) -> <a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr m a</td><td class="doc empty"> </td></tr></table></div></div><div class="top"><p class="src"><a name="v:viewT" class="def">viewT</a> :: <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a -> m (<a href="Control-Monad-Operational.html#t:ProgramViewT">ProgramViewT</a> instr m a) <a href="src/Control-Monad-Operational.html#viewT" class="link">Source</a></p><div class="doc"><p>View function for inspecting the first instruction.</p></div></div><div class="doc"><p><em>Example usage</em></p><p>List monad transformer.</p><pre> 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))</pre><p>Note that since <code><a href="Control-Monad-Operational.html#t:ProgramView">ProgramView</a></code> is a GADT, the type annotation for <code>eval</code> is mandatory.</p></div><div class="top"><p class="src"><a name="v:liftProgram" class="def">liftProgram</a> :: <a href="file:///usr/share/doc/ghc-doc/html/libraries/base-4.8.2.0/Control-Monad.html#t:Monad">Monad</a> m => <a href="Control-Monad-Operational.html#t:Program">Program</a> instr a -> <a href="Control-Monad-Operational.html#t:ProgramT">ProgramT</a> instr m a <a href="src/Control-Monad-Operational.html#liftProgram" class="link">Source</a></p><div class="doc"><p>Lift a plain sequence of instructions to a sequence
of instructions over a monad <code>m</code>.
This is the counterpart of the <code><a href="file:///usr/share/doc/ghc-doc/html/libraries/transformers-0.4.2.0/Control-Monad-Trans-Class.html#v:lift">lift</a></code> function from <code><a href="file:///usr/share/doc/ghc-doc/html/libraries/transformers-0.4.2.0/Control-Monad-Trans-Class.html#t:MonadTrans">MonadTrans</a></code>.</p><p>It can be defined as follows:</p><pre> liftProgram = eval . view
where
eval :: ProgramView instr a -> ProgramT instr m a
eval (Return a) = return a
eval (i :>>= k) = singleton i >>= liftProgram . k
</pre></div></div></div></div><div id="footer"><p>Produced by <a href="http://www.haskell.org/haddock/">Haddock</a> version 2.16.1</p></div></body></html>
|