Skip to content

Instantly share code, notes, and snippets.

@erhangundogan
Created October 18, 2021 07:59
Show Gist options
  • Save erhangundogan/968d5b2e8e9116849fbfa7e7d4d563db to your computer and use it in GitHub Desktop.
Save erhangundogan/968d5b2e8e9116849fbfa7e7d4d563db to your computer and use it in GitHub Desktop.
(* http://alaska-kamtchatka.blogspot.com/2012/07/theorems-for-free-monad-edition.html *)
module type FUNCTOR = sig
type 'a t
val fmap : ('a -> 'b) -> ('a t -> 'b t)
end
module type APPLICATIVE = sig
type 'a t
val pure : 'a -> 'a t
val ap : ('a -> 'b) t -> ('a t -> 'b t)
end
module type MONAD = sig
type 'a t
val return : 'a -> 'a t
val bind : ('a -> 'b t) -> ('a t -> 'b t)
end
module type APPLICATIVE_FUNCTOR = sig
type 'a t
include FUNCTOR with type 'a t := 'a t
include APPLICATIVE with type 'a t := 'a t
end
module ApplicativeFunctor (M : MONAD) : APPLICATIVE_FUNCTOR with type 'a t = 'a M.t
= struct
type 'a t = 'a M.t
open M
let fmap f = bind (fun x -> return (f x))
let pure = return
let ap u v = bind (fun f -> fmap f v) u
end
module Functor (F : FUNCTOR) = struct
include F
let ( <$> ) = fmap
end
module Applicative (A : APPLICATIVE) = struct
include A
let ( <*> ) = ap
end
module Monad (M : MONAD) = struct
include M
include (ApplicativeFunctor (M)
: APPLICATIVE_FUNCTOR with type 'a t := 'a t)
let ( <$> ) = fmap
let ( <*> ) = ap
let ( >>= ) m f = bind f m
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment