Monads/List monad: Difference between revisions

Add Ocaml
(Added uBasic/4tH version)
(Add Ocaml)
Line 721:
echo [0.5] --> root --> asin --> format </lang>
{{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}}==
Anonymous user