Monads/List monad: Difference between revisions

Content added Content deleted
m (syntax highlighting fixup automation)
Line 23: Line 23:


We can use a list monad in AppleScript to express set comprehension for the Pythagorean triples, but the lack of nestable first class (and anonymous) functions means that the closure can only be achieved using script objects, which makes the idiom rather less direct and transparent. AppleScript is creaking at the seams here.
We can use a list monad in AppleScript to express set comprehension for the Pythagorean triples, but the lack of nestable first class (and anonymous) functions means that the closure can only be achieved using script objects, which makes the idiom rather less direct and transparent. AppleScript is creaking at the seams here.
<lang AppleScript>-- MONADIC FUNCTIONS (for list monad) ------------------------------------------
<syntaxhighlight lang="applescript">-- MONADIC FUNCTIONS (for list monad) ------------------------------------------


-- Monadic bind for lists is simply ConcatMap
-- Monadic bind for lists is simply ConcatMap
Line 138: Line 138:
end script
end script
end if
end if
end mReturn</lang>
end mReturn</syntaxhighlight>
{{Out}}
{{Out}}
<lang AppleScript>{{3, 4, 5}, {5, 12, 13}, {6, 8, 10}, {7, 24, 25}, {8, 15, 17}, {9, 12, 15}, {12, 16, 20}, {15, 20, 25}}</lang>
<syntaxhighlight lang="applescript">{{3, 4, 5}, {5, 12, 13}, {6, 8, 10}, {7, 24, 25}, {8, 15, 17}, {9, 12, 15}, {12, 16, 20}, {15, 20, 25}}</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
Line 150: Line 150:
Still, the task example is constrained enough that we can provide an implementation like:
Still, the task example is constrained enough that we can provide an implementation like:


<lang C>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>


Line 176: Line 176:
int main() {
int main() {
task(13);
task(13);
}</lang>
}</syntaxhighlight>


Which, from the command line, might look like:
Which, from the command line, might look like:


<lang bash>$ ./monad
<syntaxhighlight lang="bash">$ ./monad
13</lang>
13</syntaxhighlight>




=={{header|C++}}==
=={{header|C++}}==
<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <vector>
#include <vector>


Line 291: Line 291:
PrintTriples(pythagoreanTriples);
PrintTriples(pythagoreanTriples);
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 317: Line 317:
=={{header|Clojure}}==
=={{header|Clojure}}==


<lang clojure>
<syntaxhighlight lang="clojure">
(defn bind [coll f] (apply vector (mapcat f coll)))
(defn bind [coll f] (apply vector (mapcat f coll)))
(defn unit [val] (vector val))
(defn unit [val] (vector val))
Line 328: Line 328:
(bind doubler)
(bind doubler)
(bind vecstr)) ; also evaluates to ["6" "8" "10"]
(bind vecstr)) ; also evaluates to ["6" "8" "10"]
</syntaxhighlight>
</lang>
=={{header|Delphi}}==
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.SysUtils}}
{{Trans|Go}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program List_monad;
program List_monad;


Line 399: Line 399:
Writeln(ml1.ToString, ' -> ', ml2.ToString);
Writeln(ml1.ToString, ' -> ', ml2.ToString);
readln;
readln;
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>[ 3, 4, 5] -> [ 8, 10, 12]</pre>
<pre>[ 3, 4, 5] -> [ 8, 10, 12]</pre>
=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
Our monadic lists will take the form (List a b c ...), ie raw lists prefixed by the List symbol.
Our monadic lists will take the form (List a b c ...), ie raw lists prefixed by the List symbol.
<lang scheme>
<syntaxhighlight lang="scheme">
;; -> and ->> are the pipeline operators
;; -> and ->> are the pipeline operators
;; (-> x f g h) = (h (g ( f x)))
;; (-> x f g h) = (h (g ( f x)))
Line 424: Line 424:
(-> '(1 -2 3 -5) List.unit (List.bind List.cube) (List.bind List.tostr))
(-> '(1 -2 3 -5) List.unit (List.bind List.cube) (List.bind List.tostr))
→ (List "1" "-8" "27" "-125")
→ (List "1" "-8" "27" "-125")
</syntaxhighlight>
</lang>


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
<lang fsharp>
<syntaxhighlight lang="fsharp">
type ListMonad() =
type ListMonad() =
member o.Bind( (m:'a list), (f: 'a -> 'b list) ) = List.concat( List.map f m )
member o.Bind( (m:'a list), (f: 'a -> 'b list) ) = List.concat( List.map f m )
Line 441: Line 441:
printf "%A" (pyth_triples 100)
printf "%A" (pyth_triples 100)
</syntaxhighlight>
</lang>


The list monad is equivalent to [[List comprehensions]] which are built into F#:
The list monad is equivalent to [[List comprehensions]] which are built into F#:


<lang fsharp>
<syntaxhighlight lang="fsharp">
// Monads/List monad . Nigel Galloway: March 8th., 2021
// Monads/List monad . Nigel Galloway: March 8th., 2021
List.iter ((+) 1>>(*) 2>>printf "%d ") [3;4;5]; printfn "";;
List.iter ((+) 1>>(*) 2>>printf "%d ") [3;4;5]; printfn "";;
Line 455: Line 455:
let test n=match valid(Ok n) with Ok g->printfn "%d is valid" g|Error e->printfn "Error: %d %s" n e
let test n=match valid(Ok n) with Ok g->printfn "%d is valid" g|Error e->printfn "Error: %d %s" n e
[5..10]|>List.iter test
[5..10]|>List.iter test
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 470: Line 470:
=={{header|Factor}}==
=={{header|Factor}}==
Factor comes with an implementation of Haskell-style monads in the <code>monads</code> vocabulary.
Factor comes with an implementation of Haskell-style monads in the <code>monads</code> vocabulary.
<lang factor>USING: kernel math monads prettyprint ;
<syntaxhighlight lang="factor">USING: kernel math monads prettyprint ;
FROM: monads => do ;
FROM: monads => do ;


{ 3 4 5 }
{ 3 4 5 }
>>= [ 1 + array-monad return ] swap call
>>= [ 1 + array-monad return ] swap call
>>= [ 2 * array-monad return ] swap call .</lang>
>>= [ 2 * array-monad return ] swap call .</syntaxhighlight>
Or:
Or:
<lang factor>{ 3 4 5 }
<syntaxhighlight lang="factor">{ 3 4 5 }
[ 1 + array-monad return ] bind
[ 1 + array-monad return ] bind
[ 2 * array-monad return ] bind .</lang>
[ 2 * array-monad return ] bind .</syntaxhighlight>
Or:
Or:
<lang factor>{
<syntaxhighlight lang="factor">{
[ { 3 4 5 } ]
[ { 3 4 5 } ]
[ 1 + array-monad return ]
[ 1 + array-monad return ]
[ 2 * array-monad return ]
[ 2 * array-monad return ]
} do .</lang>
} do .</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 494: Line 494:
=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
{{trans|Ring}}
{{trans|Ring}}
<lang freebasic>Dim As Integer m1(1 To 3) = {3,4,5}
<syntaxhighlight lang="freebasic">Dim As Integer m1(1 To 3) = {3,4,5}
Dim As String m2 = "["
Dim As String m2 = "["
Dim As Integer x, y ,z
Dim As Integer x, y ,z
Line 505: Line 505:
m2 &= "]"
m2 &= "]"
Print m2
Print m2
Sleep</lang>
Sleep</syntaxhighlight>
{{out}}
{{out}}
<pre>[8, 10, 12]</pre>
<pre>[8, 10, 12]</pre>
Line 511: Line 511:


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import "fmt"
import "fmt"
Line 545: Line 545:
ml2 := ml1.bind(increment).bind(double)
ml2 := ml1.bind(increment).bind(double)
fmt.Printf("%v -> %v\n", ml1.value, ml2.value)
fmt.Printf("%v -> %v\n", ml1.value, ml2.value)
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 555: Line 555:


Haskell has the built-in <code>Monad</code> type class, and the built-in list type already conforms to the <code>Monad</code> type class.
Haskell has the built-in <code>Monad</code> type class, and the built-in list type already conforms to the <code>Monad</code> type class.
<lang haskell>main = print $ [3,4,5] >>= (return . (+1)) >>= (return . (*2)) -- prints [8,10,12]</lang>
<syntaxhighlight lang="haskell">main = print $ [3,4,5] >>= (return . (+1)) >>= (return . (*2)) -- prints [8,10,12]</syntaxhighlight>


Or, written using <code>do</code> notation:
Or, written using <code>do</code> notation:
<lang haskell>main = print $ do x <- [3,4,5]
<syntaxhighlight lang="haskell">main = print $ do x <- [3,4,5]
y <- return (x+1)
y <- return (x+1)
z <- return (y*2)
z <- return (y*2)
return z</lang>
return z</syntaxhighlight>


Or alternately:
Or alternately:
<lang haskell>main = print $ do x <- [3,4,5]
<syntaxhighlight lang="haskell">main = print $ do x <- [3,4,5]
let y = x+1
let y = x+1
let z = y*2
let z = y*2
return z</lang>
return z</syntaxhighlight>


Using the list monad to express set comprehension for Pythagorean triples:
Using the list monad to express set comprehension for Pythagorean triples:
<lang haskell>pythagoreanTriples :: Integer -> [(Integer, Integer, Integer)]
<syntaxhighlight lang="haskell">pythagoreanTriples :: Integer -> [(Integer, Integer, Integer)]
pythagoreanTriples n =
pythagoreanTriples n =
[1 .. n] >>= (\x ->
[1 .. n] >>= (\x ->
Line 577: Line 577:
if x^2 + y^2 == z^2 then return (x,y,z) else [])))
if x^2 + y^2 == z^2 then return (x,y,z) else [])))


main = print $ pythagoreanTriples 25</lang>
main = print $ pythagoreanTriples 25</syntaxhighlight>
{{out}}
{{out}}
<pre>[(3,4,5),(5,12,13),(6,8,10),(7,24,25),(8,15,17),(9,12,15),(12,16,20),(15,20,25)]</pre>
<pre>[(3,4,5),(5,12,13),(6,8,10),(7,24,25),(8,15,17),(9,12,15),(12,16,20),(15,20,25)]</pre>


Which can be written using <code>do</code> notation:
Which can be written using <code>do</code> notation:
<lang haskell>pythagoreanTriples :: Integer -> [(Integer, Integer, Integer)]
<syntaxhighlight lang="haskell">pythagoreanTriples :: Integer -> [(Integer, Integer, Integer)]
pythagoreanTriples n = do x <- [1 .. n]
pythagoreanTriples n = do x <- [1 .. n]
y <- [x+1 .. n]
y <- [x+1 .. n]
z <- [y+1 .. n]
z <- [y+1 .. n]
if x^2 + y^2 == z^2 then return (x,y,z) else []</lang>
if x^2 + y^2 == z^2 then return (x,y,z) else []</syntaxhighlight>


Or directly as a list comprehension:
Or directly as a list comprehension:
<lang haskell>pythagoreanTriples :: Integer -> [(Integer, Integer, Integer)]
<syntaxhighlight lang="haskell">pythagoreanTriples :: Integer -> [(Integer, Integer, Integer)]
pythagoreanTriples n = [(x,y,z) | x <- [1 .. n], y <- [x+1 .. n], z <- [y+1 .. n], x^2 + y^2 == z^2]</lang>
pythagoreanTriples n = [(x,y,z) | x <- [1 .. n], y <- [x+1 .. n], z <- [y+1 .. n], x^2 + y^2 == z^2]</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
Line 598: Line 598:
That said, here is an implementation which might be adequate for the current task description:
That said, here is an implementation which might be adequate for the current task description:


<lang J>bind=: S:0
<syntaxhighlight lang="j">bind=: S:0
unit=: boxopen
unit=: boxopen


m_num=: unit
m_num=: unit
m_str=: unit@":</lang>
m_str=: unit@":</syntaxhighlight>


Task example:
Task example:


<lang J> m_str bind m_num 5
<syntaxhighlight lang="j"> m_str bind m_num 5
┌─┐
┌─┐
│5│
│5│
└─┘</lang>
└─┘</syntaxhighlight>


=={{header|Javascript}}==
=={{header|Javascript}}==


<lang javascript>
<syntaxhighlight lang="javascript">
Array.prototype.bind = function (func) {
Array.prototype.bind = function (func) {
return this.map(func).reduce(function (acc, a) { return acc.concat(a); });
return this.map(func).reduce(function (acc, a) { return acc.concat(a); });
Line 632: Line 632:


[3,4,5].bind(listy_inc).bind(listy_doub); // [8, 10, 12]
[3,4,5].bind(listy_inc).bind(listy_doub); // [8, 10, 12]
</syntaxhighlight>
</lang>




ES5 Example: Using the list monad to express set comprehension
ES5 Example: Using the list monad to express set comprehension


<lang JavaScript>(function (n) {
<syntaxhighlight lang="javascript">(function (n) {


// ENCODING A SET COMPREHENSION IN TERMS OF A LIST MONAD
// ENCODING A SET COMPREHENSION IN TERMS OF A LIST MONAD
Line 687: Line 687:
}
}


})(25);</lang>
})(25);</syntaxhighlight>


{{Out}}
{{Out}}
Line 696: Line 696:
Julia uses the function bind for binding a channel to a task, but this can be imported and overloaded.
Julia uses the function bind for binding a channel to a task, but this can be imported and overloaded.
The |> syntax in Julia can also be used to chain functions taking one argument.
The |> syntax in Julia can also be used to chain functions taking one argument.
<lang julia>julia> unit(v) = [v...]
<syntaxhighlight lang="julia">julia> unit(v) = [v...]
unit (generic function with 1 method)
unit (generic function with 1 method)


Line 721: Line 721:
8
8
10
10
</syntaxhighlight>
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>// version 1.2.10
<syntaxhighlight lang="scala">// version 1.2.10


class MList<T : Any> private constructor(val value: List<T>) {
class MList<T : Any> private constructor(val value: List<T>) {
Line 742: Line 742:
val fv = iv.bind(::doubler).bind(::letters)
val fv = iv.bind(::doubler).bind(::letters)
println(fv.value)
println(fv.value)
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 750: Line 750:
=={{header|Nim}}==
=={{header|Nim}}==
a natural use of a list-wrapped return value is when there can be more than one result from a function, for example square roots have a positive and negative solution, and the inverse sine function has multiple solutions we might be interested in.
a natural use of a list-wrapped return value is when there can be more than one result from a function, for example square roots have a positive and negative solution, and the inverse sine function has multiple solutions we might be interested in.
<lang nim>import math,sequtils,sugar,strformat
<syntaxhighlight lang="nim">import math,sequtils,sugar,strformat
func root(x:float):seq[float] = @[sqrt(x),-sqrt(x)]
func root(x:float):seq[float] = @[sqrt(x),-sqrt(x)]
func asin(x:float):seq[float] = @[arcsin(x),arcsin(x)+TAU,arcsin(x)-TAU]
func asin(x:float):seq[float] = @[arcsin(x),arcsin(x)+TAU,arcsin(x)-TAU]
Line 760: Line 760:
input.map(f).concat
input.map(f).concat


echo [0.5] --> root --> asin --> format </lang>
echo [0.5] --> root --> asin --> format </syntaxhighlight>
{{out}}<pre>@["0.79", "7.07", "-5.50", "-0.79", "5.50", "-7.07"]</pre>
{{out}}<pre>@["0.79", "7.07", "-5.50", "-0.79", "5.50", "-7.07"]</pre>


=={{header|OCaml}}==
=={{header|OCaml}}==
Defining the list monad is fairly straightforward:
Defining the list monad is fairly straightforward:
<lang ocaml>let bind : 'a list -> ('a -> 'b list) -> 'b list =
<syntaxhighlight lang="ocaml">let bind : 'a list -> ('a -> 'b list) -> 'b list =
fun l f -> List.flatten (List.map f l)
fun l f -> List.flatten (List.map f l)


let return x = [x]</lang>
let return x = [x]</syntaxhighlight>


For convenience, the example will also use the following definitions:
For convenience, the example will also use the following definitions:
<lang ocaml>let (>>) = bind (* operator for inline binding *)
<syntaxhighlight lang="ocaml">let (>>) = bind (* operator for inline binding *)
let (let*) = bind (* let pruning for easy bind *)
let (let*) = bind (* let pruning for easy bind *)


let print_str_list l =
let print_str_list l =
Format.printf "[%a]" (fun fmt -> Format.pp_print_list Format.pp_print_string fmt) l</lang>
Format.printf "[%a]" (fun fmt -> Format.pp_print_list Format.pp_print_string fmt) l</syntaxhighlight>


First example: increment and print
First example: increment and print
<lang ocaml>let incr x = return (x+1)
<syntaxhighlight lang="ocaml">let incr x = return (x+1)
let hex x = return (Format.sprintf "%#x" x)
let hex x = return (Format.sprintf "%#x" x)


Line 796: Line 796:
let* x = List.init 5 (fun x -> x) in
let* x = List.init 5 (fun x -> x) in
let* y = incr x in hex y
let* y = incr x in hex y
in print_str_list l</lang>
in print_str_list l</syntaxhighlight>


Second example: pythegorean triplets
Second example: pythegorean triplets
<lang ocaml>(* Version 1 : with explicit calls *)
<syntaxhighlight lang="ocaml">(* Version 1 : with explicit calls *)
let pythegorean_triple n =
let pythegorean_triple n =
let x = List.init n (fun x -> x) in
let x = List.init n (fun x -> x) in
Line 822: Line 822:
let* y = List.init n (fun x -> x) in
let* y = List.init n (fun x -> x) in
let* z = List.init n (fun x -> x) in
let* z = List.init n (fun x -> x) in
if x*x + y*y = z*z then return (x,y,z) else []</lang>
if x*x + y*y = z*z then return (x,y,z) else []</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
With the help of the CPAN module <code>Data::Monad</code>, we can work with list monads.
With the help of the CPAN module <code>Data::Monad</code>, we can work with list monads.
<lang perl>use strict;
<syntaxhighlight lang="perl">use strict;
use feature 'say';
use feature 'say';
use Data::Monad::List;
use Data::Monad::List;
Line 853: Line 853:
for (@{shift @triples}) {
for (@{shift @triples}) {
say keys %$_ if keys %$_;
say keys %$_ if keys %$_;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>000
<pre>000
Line 869: Line 869:
=={{header|Phix}}==
=={{header|Phix}}==
{{trans|Go}}
{{trans|Go}}
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">bindf</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">bindf</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
Line 889: Line 889:
<span style="color: #000000;">m2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bindf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bindf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">increment</span><span style="color: #0000FF;">),</span><span style="color: #000000;">double</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">m2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bindf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bindf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">increment</span><span style="color: #0000FF;">),</span><span style="color: #000000;">double</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v -&gt; %v\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">m1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">m2</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v -&gt; %v\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">m1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">m2</span><span style="color: #0000FF;">})</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 897: Line 897:
=={{header|Python}}==
=={{header|Python}}==


<lang python>"""A List Monad. Requires Python >= 3.7 for type hints."""
<syntaxhighlight lang="python">"""A List Monad. Requires Python >= 3.7 for type hints."""
from __future__ import annotations
from __future__ import annotations
from itertools import chain
from itertools import chain
Line 957: Line 957:
)
)
)
)
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 975: Line 975:
Note that this also demonstrates how to use Racket's macro system to implement the do syntax.
Note that this also demonstrates how to use Racket's macro system to implement the do syntax.


<lang racket>#lang racket
<syntaxhighlight lang="racket">#lang racket


(define (bind x f) (append-map f x))
(define (bind x f) (append-map f x))
Line 1,017: Line 1,017:


(pythagorean-triples* 25)
(pythagorean-triples* 25)
;; => '((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20))</lang>
;; => '((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20))</syntaxhighlight>


=== With functional package ===
=== With functional package ===
Line 1,023: Line 1,023:
The [https://docs.racket-lang.org/functional/interfaces.html functional] package has already implemented the list monad.
The [https://docs.racket-lang.org/functional/interfaces.html functional] package has already implemented the list monad.


<lang racket>#lang racket
<syntaxhighlight lang="racket">#lang racket


(require data/monad
(require data/monad
Line 1,038: Line 1,038:


(pythagorean-triples 25)
(pythagorean-triples 25)
;; => '((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20))</lang>
;; => '((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20))</syntaxhighlight>


=={{header|Raku}}==
=={{header|Raku}}==
Line 1,049: Line 1,049:


The * in the bind blocks are typically referred to as "whatever"; whatever + 3 etc. The guillemot (») is the hyper operator; descend into the data structure and apply the following operator/function to each member.
The * in the bind blocks are typically referred to as "whatever"; whatever + 3 etc. The guillemot (») is the hyper operator; descend into the data structure and apply the following operator/function to each member.
<lang perl6>multi bind (@list, &code) { @list.map: &code };
<syntaxhighlight lang="raku" line>multi bind (@list, &code) { @list.map: &code };


multi bind ($item, &code) { $item.&code };
multi bind ($item, &code) { $item.&code };
Line 1,055: Line 1,055:
sub divisors (Int $int) { gather for 1 .. $int { .take if $int %% $_ } }
sub divisors (Int $int) { gather for 1 .. $int { .take if $int %% $_ } }


put (^10).&bind(* + 3).&bind(&divisors)».&bind(*.base: 2).join: "\n";</lang>
put (^10).&bind(* + 3).&bind(&divisors)».&bind(*.base: 2).join: "\n";</syntaxhighlight>


{{out}}
{{out}}
Line 1,070: Line 1,070:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
# Project : Monads/List monad
# Project : Monads/List monad


Line 1,083: Line 1,083:
str = str + "]"
str = str + "]"
see str + nl
see str + nl
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 1,091: Line 1,091:
=={{header|Ruby}}==
=={{header|Ruby}}==


<lang ruby>
<syntaxhighlight lang="ruby">
class Array
class Array
def bind(f)
def bind(f)
Line 1,135: Line 1,135:


[3,4,5].bind_comp(listy_doub, listy_inc) #=> [8, 10, 12]
[3,4,5].bind_comp(listy_doub, listy_inc) #=> [8, 10, 12]
</syntaxhighlight>
</lang>


=={{header|uBasic/4tH}}==
=={{header|uBasic/4tH}}==
{{trans|Ring}}
{{trans|Ring}}
<lang>s := "[" : Push 5, 4, 3
<syntaxhighlight lang="text">s := "[" : Push 5, 4, 3


Do While Used ()
Do While Used ()
Line 1,147: Line 1,147:


Print Show (Set (s, Join (Clip (s, 2), "]")))
Print Show (Set (s, Join (Clip (s, 2), "]")))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,157: Line 1,157:
=={{header|Wren}}==
=={{header|Wren}}==
{{trans|Go}}
{{trans|Go}}
<lang ecmascript>class Mlist {
<syntaxhighlight lang="ecmascript">class Mlist {
construct new(value) { _value = value }
construct new(value) { _value = value }


Line 1,179: Line 1,179:
var ml1 = Mlist.unit([3, 4, 5])
var ml1 = Mlist.unit([3, 4, 5])
var ml2 = ml1.bind(increment).bind(double)
var ml2 = ml1.bind(increment).bind(double)
System.print("%(ml1.value) -> %(ml2.value)")</lang>
System.print("%(ml1.value) -> %(ml2.value)")</syntaxhighlight>


{{out}}
{{out}}
Line 1,191: Line 1,191:
{{trans|Ruby}}
{{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).
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{
<syntaxhighlight lang="zkl">class MList{
fcn init(xs){ var list=vm.arglist }
fcn init(xs){ var list=vm.arglist }
fcn bind(f) { list=list.apply(f); self }
fcn bind(f) { list=list.apply(f); self }
fcn toString{ list.toString() }
fcn toString{ list.toString() }
}</lang>
}</syntaxhighlight>
<lang zkl>inc:=Op("+",1); // '+(1)
<syntaxhighlight lang="zkl">inc:=Op("+",1); // '+(1)
str:="toString";
str:="toString";
MList(3,4,5).bind(inc).bind(str).println(" == (4,5,6)");
MList(3,4,5).bind(inc).bind(str).println(" == (4,5,6)");
Line 1,204: Line 1,204:


comp:=Utils.Helpers.fcomp; // comp(f,g) == f.g == f(g(x))
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>
MList(3,4,5).bind(comp(doub,inc)).println(" == (8,10,12)");</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>