/
maybe monad.fs
50 lines (42 loc) · 1.23 KB
/
maybe monad.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(* MAYBE MONAD *)
module MaybeMonad
let inline (>>=) m f = (^a : (member Bind: (_ -> ^b) -> ^b)(m,f))
let inline Unit x = (^b : (static member Unit : ^a -> ^b) x)
let inline Zero () = (^a : (static member Zero : unit -> ^a) ())
type Maybe<'a> =
|Just of 'a
|Nothing
with
member this.Bind f =
match this with
| Just a -> f a
| Nothing -> Nothing
static member Unit x = Just x
static member Zero () = Nothing
(* examples *)
let plus = fun a -> Unit (a+a)
let div = fun a -> if a=0 then Zero()
else Unit (a/a)
let test1 = Just 0 >>= plus >>= div
let test2 = Just 10 >>= div >>= plus
(***************)
let phonebook =
[("Bob", 01788665242);
("Fred", 01624556442);
("Alice", 01889985333);
("Jane", 01732187565)]
let lookup (key:'a) table :Maybe<'b> =
let rec find = function
| h::t -> if key=(fst h) then Unit (snd h)
else find t
| [] -> Zero()
in find table
let superSecretFunction =
fun a -> if a % 2 = 1 then Zero()
else Unit a
let testx1 =
lookup "Bob" phonebook >>= superSecretFunction
let testx2 =
lookup "asd" phonebook >>= superSecretFunction
let testx3 =
lookup "Alice" phonebook >>= superSecretFunction