6 people like it.
Like the snippet!
Polymorphic Maybe monad with default value.
Polymorphic (via generics) Maybe monad/computational expression with default value + Zipper
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:
51:
52:
53:
54:
55:
56:
57:
58:
|
type Maybe<'a> (defaultValue : 'a) =
member m.Bind(x : 'a option, f) = Option.bind f x
member m.Return(x : 'a) = Some(x)
member m.Zero() = None
member m.ReturnFrom(x : 'a option) = x
member m.Run(x : 'a option) =
if Option.isSome x then Option.get x
else defaultValue
type 'a Zipper = ('a list)*('a list)
let (head : 'a Zipper -> 'a option) = function
| (_,[]) -> None
| (_,h::t) -> Some h
let (right : 'a Zipper -> 'a Zipper option) = function
| (_,[]) -> None
| (l,h::t) -> Some (h::l,t)
let (left : 'a Zipper -> 'a Zipper option) = function
| ([],_) -> None
| (h::t,r) -> Some (t,h::r)
let mkzip l = ([],l)
let maybeZ = new Maybe<int Zipper>(([],[]))
let maybeE = new Maybe<int>(0)
let myz : int Zipper = ([3;2;1],[4;5;6])
let z1 = maybeZ {
let! z = left myz
let! z = left z
let! z = right z
let! z = right z
let! z = right z
return z
}
let z2 = maybeZ {
let! z = right myz
let! z = right z
let! z = right z
let! z = right z
let! z = right z
let! z = right z
return z
}
let z3 = maybeE {
return! head z1
}
let z4 = maybeE {
return! head z2
}
let z5 = maybeE {
return! head (maybeZ {
return! left myz
})
}
|
Multiple items
type Maybe<'a> =
new : defaultValue:'a -> Maybe<'a>
member Bind : x:'a option * f:('a -> 'a0 option) -> 'a0 option
member Return : x:'a -> 'a option
member ReturnFrom : x:'a option -> 'a option
member Run : x:'a option -> 'a
member Zero : unit -> 'a0 option
Full name: Script.Maybe<_>
--------------------
new : defaultValue:'a -> Maybe<'a>
val defaultValue : 'a
val m : Maybe<'a>
member Maybe.Bind : x:'a option * f:('a -> 'a0 option) -> 'a0 option
Full name: Script.Maybe`1.Bind
val x : 'a option
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
val f : ('a -> 'a0 option)
module Option
from Microsoft.FSharp.Core
val bind : binder:('T -> 'U option) -> option:'T option -> 'U option
Full name: Microsoft.FSharp.Core.Option.bind
member Maybe.Return : x:'a -> 'a option
Full name: Script.Maybe`1.Return
val x : 'a
union case Option.Some: Value: 'T -> Option<'T>
member Maybe.Zero : unit -> 'a0 option
Full name: Script.Maybe`1.Zero
union case Option.None: Option<'T>
member Maybe.ReturnFrom : x:'a option -> 'a option
Full name: Script.Maybe`1.ReturnFrom
member Maybe.Run : x:'a option -> 'a
Full name: Script.Maybe`1.Run
val isSome : option:'T option -> bool
Full name: Microsoft.FSharp.Core.Option.isSome
val get : option:'T option -> 'T
Full name: Microsoft.FSharp.Core.Option.get
type 'a Zipper = 'a list * 'a list
Full name: Script.Zipper<_>
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
val head : ('a Zipper -> 'a option)
Full name: Script.head
val h : 'a
val t : 'a list
val right : ('a Zipper -> 'a Zipper option)
Full name: Script.right
val l : 'a list
val left : ('a Zipper -> 'a Zipper option)
Full name: Script.left
val r : 'a list
val mkzip : l:'a -> 'b list * 'a
Full name: Script.mkzip
val l : 'a
val maybeZ : Maybe<int Zipper>
Full name: Script.maybeZ
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val maybeE : Maybe<int>
Full name: Script.maybeE
val myz : int Zipper
Full name: Script.myz
val z1 : int Zipper
Full name: Script.z1
val z : int Zipper
val z2 : int Zipper
Full name: Script.z2
val z3 : int
Full name: Script.z3
val z4 : int
Full name: Script.z4
val z5 : int
Full name: Script.z5
More information