The following computation sequence works without error:
type Monad_1 () =
member M.Bind (so : 'T option, bf : 'T -> 'T option) : 'T option =
match so with
| Some s -> bf s
| None -> None
member M.Delay (df : unit -> 'T) : 'T = // SEE CORRECTION 1
df ()
member M.Return (rv : 'T) : 'T option =
Some rv
let test_1 () : unit =
let m_1 = Monad_1 ()
let cero =
m_1 {
let x1 = 10
let! x2 = Some 20
let! x3 = Some 30
return x1 + x2 + x3}
match cero with
| Some cer -> printfn "%d" cer
| None -> printfn "None"
test_1 () // Output: 60
Now suppose I take the same monad and specialise it to the integer type:
type Monad_2 () =
member M.Bind (so : int option, bf : int -> int option) : int option =
match so with
| Some s -> bf s
| None -> None
member M.Delay (df : unit -> int) : int = // SEE CORRECTION 2
df ()
member M.Return (rv : int) : int option =
Some rv
let test_2 () : unit =
let m_2 = Monad_2 ()
let cero =
m_2 {
let x1 = 10
let! x2 = Some 20 // ERROR HERE: This expression was expected to have type int, but here has type int option
let! x3 = Some 30
return x1 + x2 + x3}
match cero with
| Some cer -> printfn "%d" cer
| None -> printfn "None"
test_2 () // ERROR
Can someone please explain the failure in my understanding here? Even hints would be helpful, in case it would take too long to write out a full explanation.
As per Mauricio Scheffer's comment above, the signature of Delay
is incorrect.
CORRECTION 1
M.Delay<'T> (df : unit -> 'T option) : 'T option
CORRECTION 2
M.Delay (df : unit -> int option) : int option