{"id":319,"date":"2007-02-20T20:52:43","date_gmt":"2007-02-20T20:52:43","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/2007\/02\/20\/using-monads-for-control-maybe-its-worth-a-look\/"},"modified":"2007-02-20T20:52:43","modified_gmt":"2007-02-20T20:52:43","slug":"using-monads-for-control-maybe-its-worth-a-look","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2007\/02\/20\/using-monads-for-control-maybe-its-worth-a-look\/","title":{"rendered":"Using Monads for Control: Maybe it&#039;s worth a look?"},"content":{"rendered":"<p> So, after our last installment, describing the theory of monads, and the previous posts, which focused on representing things like state and I\/O, I thought it was worth taking a moment to look at a  different kind of thing that can be done with monads. We so often think of them as being state wrappers; and yet, that&#8217;s only really a part of what we can get from them. Monads are ways of tying together almost <em>anything<\/em> that involves sequences.<\/p>\n<p><!--more--><\/p>\n<p> In previous parts of this tutorial, we&#8217;ve seen the <code>Maybe<\/code> type. It&#8217;s a useful type for all sorts of things where there <em>might<\/em> be a value. For example, a dictionary<br \/>\nlookup function would often be written something like:<\/p>\n<pre>\nlookup :: (Ord a) =&gt; Dictionary a b -&gt; a -&gt; Maybe b\n<\/pre>\n<p> You might expect <code>(Ord a) =&gt; Dictionary a b -&gt; a -&gt; b<\/code>, meaning a function from a dictionary and a value of type a to a value of type b. But that&#8217;s not a great type definition for a lookup, because then what would the function return when the key isn&#8217;t in the dictionary? <code>Maybe<\/code> gives us a way of handling that: if the key is included, we&#8217;ll return <code>Just b<\/code>; otherwise, we&#8217;ll return <code>Nothing<\/code>.<\/p>\n<p> The problem with <code>Maybe<\/code> is that anytime you use it, you need to wrap<br \/>\nthings up in pattern matches to check if a <code>Nothing<\/code> value was returned, and to extract a value if a <code>Just<\/code> was returned. That gets particularly messy if you have a <em>sequence<\/em> of things to be looked up. For example, imagine that we&#8217;re writing a program for the police. They&#8217;ve got a license plate number, and they&#8217;d like to get the phone number of the person who owns the car with that plate. But the data is in different places: there&#8217;s a list of license plate numbers associated with owners; and then there&#8217;s the telephone book which has listings of peoples names and phone numbers. So here are some trivial implementations of the basic types and lookup functions:<\/p>\n<pre>\n&gt;data LicensePlate = Plate String deriving (Eq,Show)\n&gt;\n&gt;getPlateOwner :: [(LicensePlate,String)] -&gt; LicensePlate -&gt; Maybe String\n&gt;getPlateOwner ((p, n):plates) plate\n&gt;                  | p == plate = Just n\n&gt;                  | otherwise = getPlateOwner plates plate\n&gt;getPlateOwner [] _ = Nothing\n&gt;\n&gt;data PhoneNumber = Phone String String String deriving (Eq,Show)\n&gt;         -- area code, prefix, number\n&gt;getPhoneNumberForName :: [(PhoneNumber,String)] -&gt; String -&gt; Maybe PhoneNumber\n&gt;getPhoneNumberForName ((num,name):phonebook) person\n&gt;                  | name==person = Just num\n&gt;                  | otherwise = getPhoneNumberForName phonebook person\n&gt;getPhoneNumberForName [] _ = Nothing\n<\/pre>\n<p> Suppose we had some databases for that:<\/p>\n<pre>\n&gt;plateDB = [(Plate \"abc\", \"Mark\"),(Plate \"h1a j2b\", \"Joe Random\"), (Plate \"u2k 5u1\", \"Jane Random\")]\n&gt;\n&gt;phoneDB=[(Phone \"321\" \"123\" \"3456\", \"Joe Random\"), (Phone \"345\" \"657\" \"3485\", \"Mark\"), (Phone \"588\" \"745\" \"1902\", \"Foo Bar\")]\n<\/pre>\n<p> Now, suppose we wanted to write a lookup function from plate to phone number. The naive way would be:<\/p>\n<pre>\n&gt;getPhoneForPlate :: [(LicensePlate,String)] -&gt;  [(PhoneNumber,String)] -&gt; LicensePlate -&gt; Maybe PhoneNumber\n&gt;getPhoneForPlate ldb pdb lic =\n&gt;   let person = getPlateOwner ldb lic\n&gt;   in case person of\n&gt;         Just name -&gt; getPhoneNumberForName pdb name\n&gt;         Nothing -&gt; Nothing\n<\/pre>\n<p> Now, imagine if we wanted to add another layer &#8211; we&#8217;d need to add <em>another<\/em> let\/case inside of the &#8220;<code>Just name<\/code>&#8221; case. The more we use <code>Maybe<\/code>, the messier it gets. But <code>Maybe<\/code> is a monad! So we could use:<\/p>\n<pre>\n&gt;mGetPhoneForPlate ::  [(LicensePlate,String)] -&gt; [(PhoneNumber,String)] -&gt; LicensePlate -&gt; Maybe PhoneNumber\n&gt;mGetPhoneForPlate ldb pdb lic =\n&gt;    do\n&gt;       name        phone        return phone\n<\/pre>\n<p>  What happened here is that &#8220;<code>Maybe<\/code>&#8221; as a monad gives us a great way of chaining. Anywhere in the chain, if any step returns &#8220;Nothing&#8221;, then the entire series will stop there, and return &#8220;<code>Nothing<\/code>&#8220;. Any step where it returns &#8220;<code>Just x<\/code>&#8220;, we can just capture the value as if there were no &#8220;<code>Just<\/code>&#8220;. Suddenly chains of <code>Maybe<\/code> aren&#8217;t a problem anymore.<\/p>\n<p> An important thing to notice about this is that the monad is being used as a control structure. We&#8217;ve got a <em>sequence<\/em> of operations chained together in a monad. When we evaluate the monadic sequence, the implementation of the binding operator that combines monads actually does control flow management. Let&#8217;s take a quick look at the internals of <code>Maybe<\/code> just to see how that&#8217;s done:<\/p>\n<pre>\ninstance Monad Maybe where\nreturn         = Just\nfail           = Nothing\nNothing  &gt;&gt;= f = Nothing\n(Just x) &gt;&gt;= f = f x\n<\/pre>\n<p> Pretty simple, right? <code>return<\/code> really just wraps the value in a &#8220;<code>Just<\/code>&#8220;. If there&#8217;s an error along the way, &#8220;<code>fail<\/code>&#8221; will make the monad evaluate to &#8220;<code>Nothing<\/code>&#8220;. And for chaining, &#8220;<code>Nothing<\/code>&#8221; chained with anything else results in &#8220;<code>Nothing<\/code>&#8220;; <code>(Just x)<\/code> chained with something unwraps <code>x<\/code>, and passes it to the next step in the chain. The control flow is captured in the pattern match between &#8220;<code>Nothing<\/code>&#8221; and &#8220;<code>Just x<\/code>&#8221; in the instance declaration of the &#8220;<code>&gt;&gt;=<\/code>&#8221; chaining operator.<\/p>\n<p> This basic trick, of using the chaining operator to insert control flow into monadic sequences is an incredibly useful technique, which is used by a variety of really cool monads. Some examples that we&#8217;ll look at in later installments are<br \/>\nmonads for backtracking computation (like prolog); for non-deterministic computation; and for a really remarkably elegant way of building parsers.<\/p>\n<p><em>(In fact, if you&#8217;re <b>not<\/b> very lucky, and I have time over the next couple of days to finish it, on friday I&#8217;ll post one of my own pathological programming languages, which has a parser implemented using the parsing monad. It&#8217;s a language based on Post&#8217;s tag systems, which form the most frustratingly simple Turing equivalent computing system that I know of.)<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>So, after our last installment, describing the theory of monads, and the previous posts, which focused on representing things like state and I\/O, I thought it was worth taking a moment to look at a different kind of thing that can be done with monads. We so often think of them as being state wrappers; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[89],"tags":[],"class_list":["post-319","post","type-post","status-publish","format-standard","hentry","category-haskell"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-59","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/319","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=319"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/319\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=319"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}