これは、これに対する参照の質問です: StackOverflow in continuation モナド
で、私が少し遊んだので、いくつかの説明が必要です。
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) 推論の問題。v
- OP の 2 番目のマップの例では、 value の推論f
の問題が原因でコンパイルされないことがわかりましa -> b list
たa -> b
。なぜこのように推論するのでしょうか。let v = f x
それがうまく推論できる場合。
3) VS がツールチップに不正確な型シグネチャを表示しているように思えます: モナドの Return の戻り値の型は: です('e->'f)->f
が、Bind の戻り値の型は のみ'c->'b
です。-バインドの場合('e->'f)
のみに単純化されているようですが、ここで何か不足していますか?c
明確にしてくれてありがとう、
トーマス
編集 - テストダンプ:
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