Category:Monads: Difference between revisions

moved list monad examples over
(Move Monads to Category:Monads)
 
(moved list monad examples over)
Line 39:
</lang>
 
===List Monad===
 
<lang clojure>
(defn bind [coll f] (apply vector (mapcat f coll)))
(defn unit [val] (vector val))
 
(defn doubler [n] [(* 2 n)]) ; takes a number and returns a List number
(def vecstr (comp vector str)) ; takes a number and returns a List string
 
(bind (bind (vector 3 4 5) doubler) vecstr) ; evaluates to ["6" "8" "10"]
(-> [3 4 5]
(bind doubler)
(bind vecstr)) ; also evaluates to ["6" "8" "10"]
</lang>
 
=={{header|J}}==
 
Note that J documentation mentions "monad" but that is an [[wp:Monad_(linear_algebra)|older]] ([[wp:Monad_(music)|much older]]) use of the term from what is intended here. J documentation uses "box" <code><</code>to describe the operation mentioned here.
 
That said, here is an implementation which might be adequate for the current task description:
 
<lang J>bind=: S:0
unit=: boxopen
 
m_num=: unit
m_str=: unit@":</lang>
 
Task example:
 
<lang J> m_str bind m_num 5
┌─┐
│5│
└─┘</lang>
 
=={{header|Ruby}}==
 
===List Monad===
 
<lang ruby>
class Array
def bind(f)
map(&f).reduce(:concat)
end
def self.unit(*args)
args
end
end
 
inc = -> e { Array.unit(e + 1) }
str = -> e { Array.unit(e.to_s) }
 
Array.unit(3,4,5).bind(inc).bind(str) #=> ["4", "5", "6"]
 
# Note that inc and str cannot be composed directly,
# as they don't have compatible type signature.
# Due to duck typing (Ruby will happily turn arrays into strings),
# in order to show this, a new function will have to be used:
 
doub = -> n {[2*n]}
[3,4,5].bind(inc).bind(doub) #=> [8, 10, 12]
 
# Direct composition will cause a TypeError, as Ruby cannot evaluate 2*[4, 5, 6]
comp = -> f, g {-> x {f[g[x]]}}
[3,4,5].bind(comp[doub, inc]) #=> TypeError: Array can't be coerced into Fixnum
 
# Composition needs to be defined in terms of bind
class Array
def bind_comp(f, g)
bind(g).bind(f)
end
end
 
[3,4,5].bind_comp(doub, inc) #=> [8, 10, 12]
</lang>
 
=={{header|zkl}}==
Line 137 ⟶ 63:
Void
Void
</pre>
 
===List Monad===
{{trans|Ruby}}
Here we create a class to do Monad like things. Unlike Ruby, we can't augment the baked in List/Array object so this more verbose. Also unlike Ruby, we can directly compose as we are applying the composition to each element (vs the list-as-object).
<lang zkl>class MList{
fcn init(xs){ var list=vm.arglist }
fcn bind(f) { list=list.apply(f); self }
fcn toString{ list.toString() }
}</lang>
<lang zkl>inc:=Op("+",1); // '+(1)
str:="toString";
MList(3,4,5).bind(inc).bind(str).println(" == (4,5,6)");
 
doub:=Op("*",2);
MList(3,4,5).bind(inc).bind(doub).println(" == (8,10,12)");
 
comp:=Utils.Helpers.fcomp; // comp(f,g) == f.g == f(g(x))
MList(3,4,5).bind(comp(doub,inc)).println(" == (8,10,12)");</lang>
{{out}}
<pre>
L("4","5","6") == (4,5,6)
L(8,10,12) == (8,10,12)
L(8,10,12) == (8,10,12)
</pre>
Anonymous user