Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Yes, following Luis Casillas answer, here is an implementation in clojure of the <code>Free</code> monad in clojure.</p> <pre><code> (use 'clojure.algo.monads) ;; data Free f r = Free (f (Free f r)) | Pure r (defn pure [v] {:t :pure :v v}) (defn impure [v] {:t :impure :v v }) (defn free-monad [fmap] (letfn [ (fm-result [v] (pure v)) (fm-bind [mv mf] (if (= :pure (:t mv)) (mf (:v mv)) ;; Pure a &gt;&gt;= f = f a (impure ;; Free fa &gt;&gt;= f = Free (fmap (&gt;&gt;=f) fa) ((fmap (fn [lmv] (fm-bind lmv mf))) (:v mv))))) ] { :m-result fm-result :m-bind fm-bind :m-zero ::undefined :m-plus ::undefined } ) ) </code></pre> <p>And an example from <a href="http://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html" rel="nofollow">Why free monads matter</a>:</p> <p>Definition of toy language.</p> <pre><code> ;; Toy language ;; (defn output [c n] [{:t :output :v c}, n]) (defn bell [n] [{:t :bell}, n]) (defn done [] [{:t :done}, nil]) (defn toy-fmap [f] (fn [[e c]] (if (= :done (:t e)) [e c] [e (f c)] )) ) </code></pre> <p>Definition of the monad for the toy language + helper functions</p> <pre><code> ;; (def tt-monad (free-monad toy-fmap)) (defn liftF [toy] (impure ((toy-fmap (fn [c] (pure c))) toy)) ) (defn m-output [x] (liftF (output x nil))) (defn m-bell [] (liftF (bell nil))) (defn m-done [] (liftF (done))) (defn f-m-done [_] (m-done)) </code></pre> <p>And checking some rules :</p> <pre><code> ;; return "a" &gt;&gt;= output is Free(Output "a", ()) ;; {:t :impure, :v [{:t :output, :v \a} {:t :pure, :v nil}]} (with-monad tt-monad (m-bind (m-result \a) m-output) ) ;; output "a" &gt;&gt;= return is Free(Output "a", ()) ;; {:t :impure, :v [{:t :output, :v \a} {:t :pure, :v nil}]} (with-monad tt-monad (m-bind (m-output \a) m-result) ) ;; ((output 'A' &gt;&gt; done) &gt;&gt; output 'C') (with-monad tt-monad (m-bind (m-bind (m-output \a) f-m-done) (fn [_] (m-output \c)))) ;;(output 'A' &gt;&gt; (done &gt;&gt; output 'C')) is output 'A' Done (with-monad tt-monad (m-bind (m-output \a) (fn [x] (m-bind (m-done) (fn [_] (m-output \c)))))) </code></pre> <p>This could be improved quite a lot in terms of readability of the data structure. Comments and improvements most welcome.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload