【问题标题】:Why does specialising the type of a monad lead to an error?为什么专门化 monad 的类型会导致错误?
【发布时间】:2013-05-22 18:21:03
【问题描述】:

以下计算序列可以正常工作:

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

现在假设我采用相同的 monad 并将其专门用于整数类型:

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

有人可以在这里解释我的理解失败吗?即使是提示也会有所帮助,以防写出完整的解释需要很长时间。

【问题讨论】:

标签: f# monads computation-expression


【解决方案1】:

根据 Mauricio Scheffer 的上述评论,Delay 的签名不正确。

更正1

M.Delay<'T> (df : unit -> 'T option) : 'T option

更正2

M.Delay (df : unit -> int option) : int option

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    相关资源
    最近更新 更多