Monads/List monad: Difference between revisions
Content added Content deleted
(Added uBasic/4tH version) |
(Add Ocaml) |
||
Line 721: | Line 721: | ||
echo [0.5] --> root --> asin --> format </lang> |
echo [0.5] --> root --> asin --> format </lang> |
||
{{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}}== |
|||
Defining the list monad is fairly straightforward: |
|||
<lang ocaml>let bind : 'a list -> ('a -> 'b list) -> 'b list = |
|||
fun l f -> List.flatten (List.map f l) |
|||
let return x = [x]</lang> |
|||
For convenience, the example will also use the following definitions: |
|||
<lang ocaml>let (>>) = bind (* operator for inline binding *) |
|||
let (let*) = bind (* let pruning for easy bind *) |
|||
let print_str_list l = |
|||
Format.printf "[%a]" (fun fmt -> Format.pp_print_list Format.pp_print_string fmt) l</lang> |
|||
First example: increment and print |
|||
<lang ocaml>let incr x = return (x+1) |
|||
let hex x = return (Format.sprintf "%#x" x) |
|||
(* Version 1 : With explicit calls *) |
|||
let () = |
|||
let l = bind (bind (List.init 5 (fun x -> x)) incr) hex in |
|||
print_str_list l |
|||
(* Version 2 : With >> operator *) |
|||
let () = |
|||
let l = List.init 5 (fun x -> x) >> incr >> hex in |
|||
print_str_list l |
|||
(* Version 3 : With let pruning *) |
|||
let () = |
|||
let l = |
|||
let* x = List.init 5 (fun x -> x) in |
|||
let* y = incr x in hex y |
|||
in print_str_list l</lang> |
|||
Second example: pythegorean triplets |
|||
<lang ocaml>(* Version 1 : with explicit calls *) |
|||
let pythegorean_triple n = |
|||
let x = 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 |
|||
bind x (fun x -> |
|||
bind y (fun y -> |
|||
bind z (fun z -> |
|||
if x*x + y*y = z*z then return (x,y,z) else [] |
|||
))) |
|||
(* Version 2 : with >> operator *) |
|||
let pythegorean_triple n = |
|||
List.init n (fun x -> x) >> fun x -> |
|||
List.init n (fun x -> x) >> fun y -> |
|||
List.init n (fun x -> x) >> fun z -> |
|||
if x*x + y*y = z*z then return (x,y,z) else [] |
|||
(* Version 3 : with let pruning *) |
|||
let pythegorean_triple n = |
|||
let* x = 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 |
|||
if x*x + y*y = z*z then return (x,y,z) else []</lang> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |