Skip to content

Instantly share code, notes, and snippets.

@jobjo
Last active August 29, 2015 14:11
Show Gist options
  • Select an option

  • Save jobjo/b03444db396a2f3f14ad to your computer and use it in GitHub Desktop.

Select an option

Save jobjo/b03444db396a2f3f14ad to your computer and use it in GitHub Desktop.
What if F# supported higher-kinded polymorphism?
// Functor interface.
type Functor<'F> = { map : ('T -> 'U) -> 'F<'T> -> 'F<'U> }
// Monad interface.
type Monad<'M> = {
return : 'T -> 'M<'T>
join : 'M<'M<'T>> -> 'M<'T>
}
// Monad "library" (operations over monads).
// Assuming:
// - higher-kinded polymorphism
// - polymorphic fields (existentially quantified)
type MonadUtils<'M> = {
bind : 'M<'T> -> ('T -> 'M<'S>) -> 'M<'S>
sequence : Seq<'M<'T>> -> 'M<List<'T>>
}
// Function for building a Monad Utils "library".
let buildMonadUtils (M: Monad<'M>) (F: Functor<'F>) =
let bind m g = M.join (F.map g m)
let rec sequence = function
| [] -> M.return
| x :: xs -> bind x (fun y -> bind (sequence xs) (fun ys -> y :: ys))
{
bind = bind
sequence = List.ofSeq >> sequence
}
// Functor instance for option types.
let optionFunctor = {map = Option.map}
// Monad instance for option types.
let optionMonad =
let join = function
| Some x -> x
| _ -> None
{return = Some; join = join}
// Builds the monad library for option types.
let OM = buildMonadUtils optionFunctor optionMonad
OM.sequence [Some 42 Some 11]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment