MonadsLaws test generalization

Dec 15, 2009 at 3:58 PM

It's possible to generalize the laws test using this function with F# member constraints, may be you find it useful:



let
inline MonadLaws< ^x, ^a, ^m when
^x : (member Return: ^a -> ^m)
and ^x : (member Bind: ^m -> (^a -> ^m) -> ^m)
and ^m : equality > b =

// "extract" >>= and unit from constraints:
let unit x = (^x: (member Return: ^a -> ^m) b, x)
let (>>=) m f = (^x: (member Bind: ^m -> (^a -> ^m) -> ^m) b, m, f)

quickCheck // left unit
<| fun m f a -> (unit a >>= f) = f a

quickCheck // right unit
<| fun m -> (m >>= unit) = m

quickCheck // associative
<| fun m f g -> ((m >>= f) >>= g) = (m >>= (fun x -> f x >>= g))