Clojure JIRA
https://dev.clojure.org/jira
This file is an XML representation of an issueen-us4.464925-07-2011[ALGOM-7] maybe-m breaks the monad laws.
https://dev.clojure.org/jira/browse/ALGOM-7
algo.monads<p>One of the monad laws is that (m-bind (m-result v) f) should be the same as (f v). However, this is not the case in maybe-m:</p>
<p>user=> (with-monad maybe-m (m-bind (m-result nil) nil?))<br/>
nil</p>
<p>user=> (nil? nil)<br/>
true</p>
<p>The crux of the problem is that in algo.monad's maybe-m, there is no way to wrap a nil in a Just-like container.</p>ALGOM-7maybe-m breaks the monad laws.DefectMajorClosedCompletedKonrad HinsenSeth J. GoldSat, 15 Sep 2012 15:00:36 -0500Wed, 5 Feb 2014 05:20:18 -0600Wed, 5 Feb 2014 05:20:18 -060002<p>Just realized that that demonstration doesn't actually work, because the function passed to m-bind is supposed to return a monadic value. Here's a better one:</p>
<p>user=> (with-monad maybe-m (m-bind (m-result nil) (comp m-result nil?)))<br/>
nil<br/>
user=> (with-monad maybe-m ((comp m-result nil?) nil))<br/>
true</p><p>I don't think this would be a valid example.</p>
<p>Here is an example in Haskell<br/>
Nothing >>= \x -> Just(x / 0) – => Nothing</p>
<p>; Clojure example<br/>
(with-monad maybe-m (m-bind m-zero #(/ % 0))) ; => nil<br/>
(with-monad maybe-m (= m-zero nil)) ; => true</p>
<p>;; Both examples will fail<br/>
(with-monad maybe-m (#(/ % 0) m-zero))<br/>
(with-monad maybe-m ((comp m-result #(/ % 0)) m-zero))</p>
<p>Those errors would not be possible to happen with Haskell's type system.</p>
<p>The following snippet shows it evaluates properly the monadic bind law for valid operations</p>
<p>(let [value 1<br/>
operation #(+ % 1)]<br/>
(with-monad maybe-m<br/>
(= <br/>
(m-bind (m-result value) operation)<br/>
(operation value))))</p><p>The Clojure implementation of maybe-m is based on the convention that nil is not a value, but a marker for "not a value". That's a very common convention in Clojure, so from a practical point of view this is the most useful way to implement maybe-m.</p>
<p>There are other options, and everyone is invited to implement their personal preference and use it in place of maybe-m. For example, a monadic value could be either an empty list or a list containing a single value.</p>
<p>Note that the Haskell approach of setting up a special type for the maybe-m container is not an option in a dynamically typed language. Whatever you choose to represent "no value" can be created outside of the monad and thus be used to violate the monad laws. It must be understood that the monad laws are valid only subject to the conventions of the specific monad.</p>Global Rank