2013-03-21 13 views
10

Pracuję nad rozszerzeniem camlp4 dla podobnej do notkacji do notacji w Ocaml i próbuję dowiedzieć się, w jaki sposób GHC kompiluje rekurencyjne powiązania do-zrobić (włączone z -XDoRec).
Zastanawiam się, czy możliwe jest istnienie monistycznego kombinatora punktów stałych w ścisłym języku (np. Ocaml/F #/SML/...)?
Jeśli tak, jak może wyglądać? Czy byłoby to bardzo przydatne?MonadFix w ścisłym języku

Odpowiedz

14

F składni wyrażenie # obliczeń (związane z Haskell do) obsługuje rekursji:

let rec ones = seq { 
    yield 1 
    yield! ones } 

ta jest obsługiwana, ponieważ budowniczy obliczenia musi obsługiwać Delay operację oprócz innych monadycznej (lub MonadPlus) operacji. Kod jest tłumaczona na coś takiego:

let rec ones = 
    seq.Combine 
    (seq.Yield(1), 
     seq.Delay(fun() -> seq.YieldFrom(ones))) 

Rodzaj Delay jest na ogół (unit -> M<'T>) -> M<'T> i Sztuką jest to, że owija obliczeń z efektami (lub bezpośrednim rekurencyjnego odniesienia) do opóźnionego obliczeń, które wyceniane są żądanie.

Jeśli chcesz dowiedzieć się więcej o tym, jak mechanizm działa w F #, a następnie dwa następujące dokumenty są istotne:

Pierwszy z nich opisuje jak F # obliczeniowa składnia wyrażeń została zniekształcona (i jak wstawiono Delay - i ogólnie, jak F # łączy opóźnione i chętne obliczenia z efektami), a druga opisuje, w jaki sposób F # obsługuje let rec deklaracje z wartościami - np. Wartość ones powyżej.

+0

Tak, nie - nie jest to możliwe w ściśle ścisły sposób. Ponieważ wszystkie języki funkcjonalne mają pewną koncepcję lenistwa (głównie za pomocą funkcji, zamknięć i zmiennych) - jest to możliwe w "ścisłych językach" poprzez leniwy konstrukt. –

+0

Często lenistwo już tam jest, ale jeśli twoja monada jest za abstrakcyjnym typem, OCaml nie pozwoli ci go wykorzystać - "Ten rodzaj ekspresji nie jest dozwolony jako prawa strona" niech rec ". W takich przypadkach musisz użyć fałszywych argumentów 'unit' (lub" leniwych ", jeśli potrzebujesz zapamiętania ...) – lukstafi