2013-07-22 17 views
5

Bu, bu konuda bir referans sorudur: StackOverflow in continuation monad
kimlerle biraz oynadım ve birkaç açıklamaya ihtiyacım var.Gecikme, yığın akışını önlemek için devam eden monad'da tam olarak nasıl çalışır?

cBind (map xs) (fun xs -> cReturn (f x :: xs)) 

cBind (fun c -> map xs c) (fun xs -> cReturn (f x :: xs)) 

Yani tam olarak ne olduğunu anlamıyorum:

member this.Delay(mk) = fun c -> mk() c 

bu arasındaki toyvo tarafından gösteriyordu hesaplamalı iş akışında davranış diffrence yapmasına neden:

1) Bu herhalde hile, ne zaman (fun c -> map xs c) yalnızca (map xs)

farklı gösterimidir. ence sorunu. - OP'nin ikinci harita örneğinde, v değeri ile çıkarım problemi nedeniyle derleme yapılmadığını öğrendim, çünkü, yerine a -> b list. Neden bu şekilde aşıyor? let v = f x durumunda iyi sonuç alacaktır.

3) VS tooltips yanlış tipi imzalarını gösteren geliyor bana: Monad en Return dönüş türüdür: ('e->'f)->f, Bind dönüş türü yalnızca 'c->'b iken. -Bindiler ('e->'f)'u Bind durumunda sadece c'a basitleştiriyor mu, yoksa burada bir şey mi özlüyorum? açıklama için

sayesinde
tomas

Düzen - test dökümü: 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" 

:
haritası [1; 2] harita [2] haritası [] cBind [] haritası [] cBind [3] harita [2] haritası [] cBind [] haritası [] [2; 3]

harita:
harita [1; 2] harita [2] harita [] cBind [] cBind [3] [2; 3]

Düzenleme 2. soruya:

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 
+0

İkinci sorunuzla ilgili olarak, çıkarım benim için gayet iyi görünüyor. – kvb

+0

Eğer ben uncomment // let! .. bana verir: Type mismatch. Bir 'bir ama verilen' bir liste bekliyor – tomasK

+0

Ben sonuncusu görmek hata - benim Bind tanımı - 1 gibi aynı günlüğü - aptalca bana ilginiz için teşekkürler. – tomasK

cevap

3

mesele o fun c -> map xs cmap xs aynı değil tam olarak. Bir anlamda aynı "anlam" a sahipler, ancak çalışma zamanı semantikleri farklıdır. İkinci durumda, ifadenin değerlendirilmesi, bir argüman olarak xs ile map işlevine yapılan bir çağrıda sonuç verir (sonuç olarak başka bir işlev döndürür). Öte yandan, fun c -> map xs c'un değerlendirilmesi'un map numaralı telefona derhal çağrılmasını sağlamaz! Sonuç işlevi gerçekte uygulanana kadar map numaralı çağrıya geçilir. Yığın taşmasını önleyen kritik fark budur.

Diğer sorularınızla ilgili olarak, ikinci sorunuzda ne sorduğunuzu tam olarak anlayamıyorum. Üçüncü sorunuz için derleyici, Bind için mümkün olan en genel türden çıktı. Beklediğiniz geleneksel türün bundan daha spesifik olması doğrudur, ancak kesinlikle gerekli olandan daha geniş bir bağlamda Bind'u arayabileceğiniz bir sorun değildir. Daha spesifik bir tür istiyorsanız, her zaman imzayı kısıtlamak için ek açıklamalar ekleyebilirsiniz.

+0

İkinci sorgumla ilgili olarak, bu ikinci işlevin fonksiyonunu derlemeye çalıştığınızda sorunun ne olduğunu göreceksiniz - fonksiyon parametresinin türü ** f ** bana beklenmedik bir durumdur. – tomasK

+0

- "haritaya anında bir aramayla sonuçlanmıyor" - fakat cBind değerlendirilmeden önce benim test dökümünde yaptığım gibi - benim düzenle ... – tomasK

+1

@tomasK - Uygulamanız hatalı çünkü 'cbind' girişinizde. Bu satırı sadece "printfn" cbind "' olarak değiştirin ve "map_fixed" in gerçekten 'map' çağrısını geciktirdiğini göreceksiniz. – kvb

İlgili konular