Difference between revisions of "Monad (sans metaphors)"

From HaskellWiki
Jump to navigation Jump to search
m
m
 
(12 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
[[Category:Glossary]]
 
[[Category:Glossary]]
  +
[[Category:Monad|*]]
  +
<div style="border-left:1px solid lightgray; padding: 1em" alt="blockquote">
  +
Think of a monad as a spacesuit full of nuclear waste in the ocean next to a container of apples. Now, you can't put oranges in the spacesuit or the nuclear waste falls in the ocean, but the apples are carried around anyway, and you just take what you need.
  +
  +
<tt>[[QuotesPage|Don Stewart.]]</tt>
  +
</div>
   
 
=== Introduction ===
 
=== Introduction ===
Many discussions of Haskell Monads seek to explain them through the use of a variety of metaphors. This page attempts to simply provide a more technical yet straightforward description of Monads in Haskell.
+
Many discussions of Haskell [[Monad|monads]] seek to explain them through the use of a variety of metaphors. This page attempts to simply provide a more technical yet straightforward description of monads as defined by Haskell.
  +
 
=== So what ''is'' a monad? ===
 
In Haskell, a monad is a type constructor with two operations, implementing a standard interface and following a few simple rules:
  +
 
* The <code>Monad</code> type class tells you the interface (what operations you've got, and their types),
  +
* the monad laws tell you what all types implementing that interface should have in common.
   
  +
The monadic interface gives you two operations:
This article originally appeared as a post to the Haskell-cafe mailing list by Claus Reinke on 2 August 2007.
 
  +
* one to stuff things into a monadic thing: <code>return</code>,
  +
* and one to chain two monadic things together: <code>(>>=)</code>.
  +
The chaining explicitly caters for information flowing from the first to the second parameter of <code>(>>=)</code>.
   
 
The monad laws tell you two useful facts about monadic things thrown together in that way: whatever it is the monad does, anything just thrown into it will take no part in that action, and whichever way you use that chaining operation, the structure of chaining is irrelevant - only the ordering of chained monadic things matters.
=== So what ''is'' a Monad? ===
 
A Monad is a type constructor with two operations, implementing a standard interface and following a few simple rules.
 
   
 
There are usually other ways to create "primitive" monadic things, which can be combined into complex monadic structures using the operations of the monadic interface.
The Monad type class tells you the interface (what operations you've got, and their types), the Monad laws tell you what all types implementing that interface should have in common.
 
   
 
There usually is an abstract way to interpret monadic structures built in this way - a <i>run</i> operation of some kind. Examples include:
The Monadic interface gives you two operations: one to throw things into a Monad thing (<hask>return</hask>), and one to chain two Monad things together <hask>(>>=)</hask>. The chaining explicitly caters for information flowing from the first to the second parameter of <hask>(>>=)</hask>.
 
   
  +
* <code>IO</code>: The "primitive monadic things" are basic I/O operations. The <i>run</i> operation exists outside the language, to be applied to <code>Main.main</code>. <code>return</code> puts its argument into a simple <code>IO</code> thing which, if used, merely produces that original argument. <code>(>>=)</code> arranges <code>IO</code> monadic structures sequentially, starting with the leftmost innermost I/O operation in the structure and applying the second argument of <code>(>>=)</code> to the result of executing the first.
The Monad laws tell you two useful facts about monad things thrown together in that way: whatever it is the Monad does, anything just thrown into it will take no part in that action, and whichever way you use that chaining operation, the
 
structure of chaining is irrelevant - only the ordering of chained Monad things matters.
 
   
  +
* <code>[]</code>: The "primitive monadic things" are lists. The <i>run</i> operation is the identity, i.e the lists are directly exposed as data structures. <code>return</code> creates a singleton list. <code>(>>=)</code> applies its second argument to each element of its first argument and concatenates the results (<code>concatMap</code>).
There are usually other ways to create 'primitive' Monadic things, which can be combined into complex Monadic structures using the operations from the Monad interface.
 
   
  +
Sometimes the monadic type provides the <i>run</i> operation as part of its interface:
There is usually a way to interpret Monadic structures built in this way - a 'run' operation of some kind. Examples include:
 
   
* I/O: The 'primitive Monadic things' are basic I/O operations. The 'run' operation is outside the language, applied to 'Main.main', and interprets (abstract) IO Monad structures sequentially, starting with the leftmost innermost I/O operation in the structure and applying the second argument of <hask>(>>=)</hask> to the result of executing the first.
+
* <code>State</code>: The "primitive monadic things" are operations on a state type, returning a result and a state. The <i>run</i> operation is provided by <code>runState</code>, wich applies a (possibly) complex monadic thing to an input state, returning a result and a (modified) state. <code>return</code> returns its parameter, passing its input state unchanged. <code>(>>=)</code> applies its first parameter to the input state, applies its second parameter to the result value and result state of the first.
   
* []: The 'primitive Monadic things' are lists. The 'run' operation is the identity, i.e the lists are directly exposed as data structures. <hask>return</hask> creates a singleton list. <hask>(>>=)</hask> applies its second argument to each element of its first argument and concatenates the results (<hask>concatMap</hask>).
+
* <code>ST</code>: The "primitive monadic things" are operations on an abstract, <i>encapsulated</i> state type. The <i>run</i> operation is provided by <code>runST</code>, which obtains the result of an <code>ST</code> thing, through the use of private state and an extension of the regular Haskell type system. <code>return</code> puts its argument into a simple <code>ST</code> thing which, if used, merely produces that original argument. <code>(>>=)</code> establishes the ordering of <code>ST</code> things by applying its second argument to the result of executing the first.
   
  +
== Original source ==
* State: The 'primitive Monadic things' are operations on a state type, returning a result and a state. 'run' is <hask>runState</hask> and applies a (possibly) complex Monadic thing to an input state, returning a result and a (modified) state. <hask>return</hask> returns its parameter, passing its input state unchanged. <hask>(>>=)</hask> applies its first parameter to the input state, applies its second parameter to the result value and result state of the first.
 
  +
* Claus Reinke on Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2007-August/029851.html Monad Description For Imperative Programmer]

Latest revision as of 08:53, 21 September 2021

Think of a monad as a spacesuit full of nuclear waste in the ocean next to a container of apples. Now, you can't put oranges in the spacesuit or the nuclear waste falls in the ocean, but the apples are carried around anyway, and you just take what you need.

Don Stewart.

Introduction

Many discussions of Haskell monads seek to explain them through the use of a variety of metaphors. This page attempts to simply provide a more technical yet straightforward description of monads as defined by Haskell.

So what is a monad?

In Haskell, a monad is a type constructor with two operations, implementing a standard interface and following a few simple rules:

  • The Monad type class tells you the interface (what operations you've got, and their types),
  • the monad laws tell you what all types implementing that interface should have in common.

The monadic interface gives you two operations:

  • one to stuff things into a monadic thing: return,
  • and one to chain two monadic things together: (>>=).

The chaining explicitly caters for information flowing from the first to the second parameter of (>>=).

The monad laws tell you two useful facts about monadic things thrown together in that way: whatever it is the monad does, anything just thrown into it will take no part in that action, and whichever way you use that chaining operation, the structure of chaining is irrelevant - only the ordering of chained monadic things matters.

There are usually other ways to create "primitive" monadic things, which can be combined into complex monadic structures using the operations of the monadic interface.

There usually is an abstract way to interpret monadic structures built in this way - a run operation of some kind. Examples include:

  • IO: The "primitive monadic things" are basic I/O operations. The run operation exists outside the language, to be applied to Main.main. return puts its argument into a simple IO thing which, if used, merely produces that original argument. (>>=) arranges IO monadic structures sequentially, starting with the leftmost innermost I/O operation in the structure and applying the second argument of (>>=) to the result of executing the first.
  • []: The "primitive monadic things" are lists. The run operation is the identity, i.e the lists are directly exposed as data structures. return creates a singleton list. (>>=) applies its second argument to each element of its first argument and concatenates the results (concatMap).

Sometimes the monadic type provides the run operation as part of its interface:

  • State: The "primitive monadic things" are operations on a state type, returning a result and a state. The run operation is provided by runState, wich applies a (possibly) complex monadic thing to an input state, returning a result and a (modified) state. return returns its parameter, passing its input state unchanged. (>>=) applies its first parameter to the input state, applies its second parameter to the result value and result state of the first.
  • ST: The "primitive monadic things" are operations on an abstract, encapsulated state type. The run operation is provided by runST, which obtains the result of an ST thing, through the use of private state and an extension of the regular Haskell type system. return puts its argument into a simple ST thing which, if used, merely produces that original argument. (>>=) establishes the ordering of ST things by applying its second argument to the result of executing the first.

Original source