2013-03-21 8 views
10

Sto lavorando sull'estensione camlp4 per la notazione haskell-like in Ocaml, e sto cercando di capire come GHC compila ricorsive do-bindings (abilitato con -XDoRec).
Mi chiedo se è possibile che il combinatore di fixpoint monadico esista in un linguaggio stretto (come Ocaml/F #/SML/...)?
Se sì, come può essere? Sarebbe molto utile?MonadFix in linguaggio stretto

risposta

14

La sintassi espressione # computazione F (correlate a Haskell do) supporta ricorsione:

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

Ciò è supportato poiché il costruttore calcolo deve sostenere Delay operazione oltre ad altre monadic (o MonadPlus) operazioni. Il codice è tradotto in modo seguente:

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

il tipo di Delay è, in generale, (unit -> M<'T>) -> M<'T> e il trucco è che avvolge un calcolo con effetti (o immediato riferimento ricorsivo) in un calcolo ritardato che viene valutata sulla richiesta.

Se volete saperne di più su come il meccanismo funziona in F #, allora le seguenti due carte sono rilevanti:

Il primo descrive come la F # la sintassi delle espressioni di calcolo è desugared (e come è inserito Delay - e in generale, come F # combina i calcoli ritardati e desiderosi con gli effetti) e il secondo descrive come F # gestisce let rec dichiarazioni con valori - come il valore ones sopra.

+0

Quindi, no - non è possibile in modo puramente rigoroso. Dal momento che tutti i linguaggi funzionali hanno un concetto di pigrizia (principalmente usando funzioni, chiusure e variabili) - è possibile in "linguaggi rigorosi" tramite costrutti pigri. –

+0

Spesso la pigrizia è già lì, ma se la tua monade è dietro un tipo astratto, OCaml non ti permetterà di sfruttarla - "Questo tipo di espressione non è consentita come parte di destra di 'let rec''. Hai bisogno di argomenti spuri 'unit' in questi casi (o forse" pigri "se hai bisogno della memoizzazione ...) – lukstafi