这是一个参考问题:StackOverflow in continuation monad
,我和他玩了一点,需要一些澄清。
1)我想这是:
member this.Delay(mk) = fun c -> mk () c
使计算工作流中的行为在这些之间产生如 toyvo 所示的差异:
cBind (map xs) (fun xs -> cReturn (f x :: xs))
cBind (fun c -> map xs c) (fun xs -> cReturn (f x :: xs))
所以我不完全明白什么是诀窍,什么时候
(fun c -> map xs c)
只是不同的符号(map xs)
2)推理问题。- 在 OP 的第二个地图示例中,我发现它由于v
值的推断问题而无法编译,因为它推断f
为a -> b list
,而不是所需的a -> b
。为什么它以这种方式推断?万一let v = f x
它会很好地推断出来。
3)在我看来,VS 在工具提示中显示了不准确的类型签名:monad 的 Return 的返回类型为:('e->'f)->f
,而 Bind 的返回类型仅为'c->'b
。- 似乎它('e->'f)
仅c
在 Bind 情况下简化,或者我在这里遗漏了什么?
谢谢你的澄清,
托马斯
编辑 - 测试转储:
let cReturn x = fun k -> k x
let cBind m f =
printfn "cBind %A" <| m id
fun c -> m (fun a -> f a c)
let map_fixed f xs =
let rec map xs =
printfn "map %A" xs
match xs with
| [] -> cReturn []
| x :: xs -> cBind (fun c -> map xs c) (fun xs -> cReturn (f x :: xs))
map xs (fun x -> x)
let map f xs =
let rec map xs =
printfn "map %A" xs
match xs with
| [] -> cReturn []
| x :: xs -> cBind (map xs) (fun xs -> cReturn (f x :: xs))
map xs (fun x -> x)
[1..2] |> map_fixed ((+) 1) |> printfn "%A"
[1..2] |> map ((+) 1) |> printfn "%A"
map_fixed:
地图 [1; 2]地图[2]地图[]cBind[]地图[]cBind[3]地图[2]地图[]cBind[]地图[][2; 3]
地图:
地图[1;2]地图[2]地图[]cBind[]cBind[3][2; 3]
编辑问题2:
let map f xs =
let rec map xs =
cont {
match xs with
| [] -> return []
| x :: xs ->
let v = f x // Inference ok
//let! v = cont { return f x } // ! Inference issue - question 2
let! xs = map xs
return v :: xs
}
map xs id