Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Monad (functional programming)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Program logging === The following code is pseudocode. {{anchor|Sample adjunct supposition}}Suppose we have two functions <code>foo</code> and <code>bar</code>, with types <syntaxhighlight lang="haskell"> foo : int -> int bar : int -> int </syntaxhighlight> That is, both functions take in an integer and return another integer. Then we can apply the functions in succession like so: <syntaxhighlight lang="haskell"> foo (bar x) </syntaxhighlight> Where the result is the result of <code>foo</code> applied to the result of <code>bar</code> applied to <code>x</code>. But suppose we are debugging our program, and we would like to add logging messages to <code>foo</code> and <code>bar</code>. So we change the types as so: <syntaxhighlight lang="haskell"> foo : int -> int * string bar : int -> int * string </syntaxhighlight> So that both functions return a tuple, with the result of the application as the integer, and a logging message with information about the applied function and all the previously applied functions as the string. Unfortunately, this means we can no longer [[Function composition|compose]] <code>foo</code> and <code>bar</code>, as their input type <code>int</code> is not compatible with their output type <code>int * string</code>. And although we can again gain composability by modifying the types of each function to be <code>int * string -> int * string</code>, this would require us to add boilerplate code to each function to extract the integer from the tuple, which would get tedious as the number of such functions increases. {{anchor|pasteInAdjunction}} Instead, let us define a helper function to abstract away this boilerplate for us: <syntaxhighlight lang="haskell"> bind : int * string -> (int -> int * string) -> int * string </syntaxhighlight> <code>bind</code> takes in an integer and string tuple, then takes in a function (like <code>foo</code>) that maps from an integer to an integer and string tuple. Its output is an integer and string tuple, which is the result of applying the input function to the integer within the input integer and string tuple. In this way, we only need to write boilerplate code to extract the integer from the tuple once, in <code>bind</code>. Now we have regained some composability. For example: <syntaxhighlight lang="haskell"> bind (bind (x,s) bar) foo </syntaxhighlight> Where <code>(x,s)</code> is an integer and string tuple.{{efn|name= paste|1= In this case, the <code>bind</code> has ''pasted'' in a <code>string</code> where previously only an <code>integer</code> had been; that is, the programmer has constructed an [[Adjoint functors|adjunction]]: a tuple <code>(x,s)</code>, denoted <code>int * string</code> in the pseudocode [[#pasteInAdjunction|Β§ above]].}} To make the benefits even clearer, let us define an infix operator as an alias for <code>bind</code>: <syntaxhighlight lang="haskell"> (>>=) : int * string -> (int -> int * string) -> int * string </syntaxhighlight> So that <code>t >>= f</code> is the same as <code>bind t f</code>. Then the above example becomes: <syntaxhighlight lang="haskell"> ((x,s) >>= bar) >>= foo </syntaxhighlight> Finally, we define a new function to avoid writing <code>(x, "")</code> every time we wish to create an empty logging message, where <code>""</code> is the empty string. <syntaxhighlight lang="haskell"> return : int -> int * string </syntaxhighlight> Which wraps <code>x</code> in the tuple described above. The result is a pipeline for logging messages: <syntaxhighlight lang="haskell"> ((return x) >>= bar) >>= foo </syntaxhighlight> That allows us to more easily log the effects of <code>bar</code> and <code>foo</code> on <code>x</code>. <code>int * string</code> denotes a pseudo-coded '''monadic value'''.{{efn|name= paste}} <code>bind</code> and <code>return</code> are analogous to the corresponding functions of the same name. In fact, <code>int * string</code>, <code>bind</code>, and <code>return</code> form a monad.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)