Skip to content

Instantly share code, notes, and snippets.

@Leonidas-from-XIV
Created February 10, 2017 22:08
Show Gist options
  • Save Leonidas-from-XIV/26c30b70f2626c1d526f8eaaaa3419ec to your computer and use it in GitHub Desktop.
Save Leonidas-from-XIV/26c30b70f2626c1d526f8eaaaa3419ec to your computer and use it in GitHub Desktop.
Small example of how the `with` construct on modules works
module type Mapable = sig
type 'a t
val map : ('a -> 'b) -> 'a t -> 'b t
val pure : 'a -> 'a t
val unsafe_perform_io : 'a t -> 'a
end
module OptionMapper : Mapable
(* comment out the following line to see difference in behaviour *)
with type 'a t = 'a option
(* this exposes type t to be 'a option even outside the module *)
= struct
type 'a t = 'a option
let map f = function
| Some a -> Some (f a)
| None -> None
let pure v = Some v
let unsafe_perform_io = function
| Some a -> a
| None -> failwith "invalid"
end
(* this wraps the value 4 in an abstract t type using `pure`
* and unwraps it using `unsafe_perform_io` *)
let always_valid =
OptionMapper.unsafe_perform_io
(OptionMapper.map (fun x -> 2 * x) (OptionMapper.pure 4))
(* this uses 'a option direct and the result is 'a option which
* can be accessed directly, since t is exposed to be of 'a option *)
let only_valid_if_exposed =
OptionMapper.map (fun x -> 2 * x) (Some 4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment