type F<'a> = F of 'a
module Functor =
// Def
// map : f:('a -> 'b) -> F<'a> -> F<'b>
let map f (F x) = F (f x)
let x = F 123
// Laws
// 1. map id x = x
printfn "equal %b" (map id x = x)
// 2. (map f x) o (map g x) = map (f o g) x
let f x = x + 100
let g x = x - 1
let fg = map f >> map g
let h = map (f >> g)
printfn "equal %b" (fg x = h x)
module Applicative =
open Functor
// Def
// apply : F<('a -> 'b)> -> F<'a> -> F<'b>
let apply (F f) (F x) = F (f x)
// return : x:'a -> F<'a>
let ``return`` x = F x
let x = F 123
// Laws
// 1. map f x = apply (return f) x
let f x = x + 100
printfn "equal %b" (map f x = apply (``return`` f) x)
module Monad =
open Functor
open Applicative
// Def
// bind : f:('a -> F<'b>) -> F<'a> -> F<'b>
let bind (f: 'a -> F<'b>) (F x) = f x
let mx = F 123
// Laws
// 1. bind f (return x) = f x
let f x = F (x + 100)
printfn "equal %b" (bind f (``return`` 123) = f 123)
// 2. bind return x = x
printfn "equal %b" (bind ``return`` mx = mx)
// 3. mx.bind(x -> f(x).bind(g)) = mx.bind(f).bind(g)
// or
// bind (x -> bind g (f x)) mx = bind g (bind f mx)
let g x = F(x - 1)
let p1 = bind g (bind f mx)
let p2 = bind (fun x -> bind g (f x)) mx
printfn "equal %b" (p1 = p2)
Last active
April 14, 2020 12:20
-
-
Save serjKim/55a8f3881fd6200a99378ae8286645cf to your computer and use it in GitHub Desktop.
F#: Functor, Applicative, Monad
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment