これはこれに関する参考質問です。StackOverflow in continuation monad
私は少し演奏し、いくつかの説明が必要です。スタックオーバフローを防ぐために、ディレイは連続モナドでどのように正確に機能しますか?
1)私はこれを仮定:
member this.Delay(mk) = fun c -> mk() c
は、これらの間のtoyvoで示したような計算ワークフローの動作がdiffrenceを行います:
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の2番目のマップの例では、v
という値の推論問題のためにコンパイルされないことがわかりました。これはの代わりにをa -> b list
と推定しています。なぜそれがこのように推測するのか? let v = f x
の場合、それはよく推測するでしょう。
3)VSがツールチップで不正確な型シグネチャを示していることに私には思える:モナドのリターンの 戻り値の型は次のとおりです。('e->'f)->f
、バインドの戻り値の型が唯一の'c->'b
ている間。 - これは、バインドケースで('e->'f)
をc
に単純化しているようですか、ここに何かがありませんか?明確化のため
おかげで、
トマス
編集 - テストダンプ:MAP_FIXED
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"
:
マップ[1。 [] CBIND [] 地図[] [2 2] マップ[2] マップ[] CBIND [] 地図[] CBIND [3] マップ[2] マップ。 3]
地図:
map [1; 2] map [2] map [] 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
2番目の質問に関して、推論は私のためにうまくいくようです。 – kvb
私は// let!のコメントを外すと、それは私に与えられます:型の不一致。期待していますが、リストを与えました – tomasK
私は間違いを見ます - 私のバインドの定義にありました - ポイント1と同様のログです - 愚かな私、関心をお寄せいただきありがとうございます。 – tomasK