Skip to main content

Meetup 23: Introduction to using Buck2 with OCaml

· 3 min read
Manas Jayanth
Managing Partner at Dining Philosophers, LLP.

Shubham Kumar lead the discussion on using OCaml with Buck2.

Additionally, Patate started a discussion about how monads unify exceptions with regular values. They also unify IO with regular values. My take, adding to his point, was how monads let us parameterise the execution model - they help us detach the meaning of computations from their representation and simply tell us what computation depends on what. The execution model, which could be swapped, then decides if it's an IO or error handling.

Here's a snippet that Patate graciously contributed

(* The program we are interested in is below.
* here are some preliminary definitions *)

(* IO monad *)
module IO: sig
type 'a t
val return: 'a -> 'a t
val bind: 'a t -> ('a -> 'b t) -> 'b t
val both: 'a t -> 'b t -> ('a * 'b) t
val wrap: (unit -> 'a) -> 'a t
val run: 'a t -> 'a
end = struct
type 'a t = unit -> 'a
let return x () = x
let bind io f () = f (io ()) ()
let both a b () = let a_result = a () in a_result, b ()
let wrap = Fun.id
let run io = io ()
end

(* Identity monad *)
module Id = struct
let return = Fun.id
let bind = ( |> )
let both a b = a, b
let run = Fun.id
end

(* ignores are for avoiding "unused" warnings *)
let () = ignore IO.(return, bind, both, wrap, run)
let () = ignore Id.(return, bind, both, run)

module Color = struct
type t = Red | Green | Blue

let to_string = function
| Red -> "red"
| Green -> "green"
| Blue -> "blue"

let of_string = function
| "red" -> Red
| "green" -> Green
| "blue" -> Blue
| s -> raise @@ Invalid_argument ("string_of_color \"" ^ s ^ "\"")
end

module IO_behaviour = struct
include IO
let get_name = IO.wrap (fun () -> input_line stdin)
let get_age = IO.wrap (fun () -> input_line stdin |> int_of_string)
let get_favorite_color = IO.wrap (fun () -> input_line stdin |> String.trim |> Color.of_string)
end
module Normal_behaviour = struct
include Id
let get_name = "patate"
let get_age = 42
let get_favorite_color = Color.Blue
end
let () = ignore (IO_behaviour.(get_name, get_age, get_favorite_color), Normal_behaviour.(get_name, get_age, get_favorite_color))
open Normal_behaviour
let () = ignore (get_name, get_age, get_favorite_color)

(* Program starts here *)

module Behaviour = Normal_behaviour
(* module Behaviour = Normal_behaviour *)

let ( let* ) = Behaviour.bind
let ( and* ) = Behaviour.both
let () = ignore (( let* ), ( and* ))

let result =
(*let open Behaviour in*)
let name = get_name
and age = get_age
and favorite_color_string = get_favorite_color in
(*Behaviour.return
@@*) Printf.sprintf
"%s is %dyo and likes %s"
name
age
(Color.to_string favorite_color_string)

let () = print_endline ((*Behaviour.run*) result)

When is the next meetup?

Checkout Upcoming Meetups

Stay in touch with us


Twitter: https://x.com/ReasonBangalore

Discord: https://discord.com/invite/Ytr36fRC4C