2017-10-19 9 views
3

dieses Programm vor:Idris - lazy evaluation Ausgabe

module test 

import Effects 
import Effect.StdIO 

(>>==) : Maybe a -> Lazy (a -> Maybe b) -> Maybe b 
(>>==) Nothing (Delay map) = Nothing 
(>>==) (Just x) (Delay map) = map x 

nothing : String -> Eff (Maybe String) [STDIO] 
nothing s = do 
    putStrLn s 
    pure Nothing 

func : Maybe String -> String -> Maybe String 
func Nothing _ = Nothing 
func (Just s) t = Just (s ++ t) 

test : Eff() [STDIO] 
test = do 
    let m = !(nothing "a") >>== (func !(nothing "b")) 
    putStrLn "end" 

main : IO() 
main = run test 

da die rechte Seite >>== faul deklariert und !(nothing "a") kehrt Nothing, ich würde erwarten, dass die rechte Seite von >>== würde nicht ausgewertet werden.

Aber eigentlich ist es ausgewertet werden, und ich kann nicht verstehen, warum ...

Allgemeiner gesagt, ich versuche Eff Berechnungen verketten, die vielleicht zurückkehren und die Ausführung zu stoppen, als ich die ersten Nothing

bekommen

Antwort

0

Desugar der! Notation.

test = do 
    x <- nothing "a" 
    y <- nothing "b" 
    let m = x >>== (func y) 
    putStrLn "end" 

Klar "a", "b" und "Ende" werden alle gedruckt werden, aber func kann nicht ausgewertet werden.

Ich denke, Sie müssen definieren >>== auf (einige) Eff Werte, anstatt direkt auf Maybe s.

HTH

+0

Was würde ich eigentlich gerne, dass die Berechnung beendet, nachdem 'nichts "a"', so dass ' "b"' nie gedruckt wird. Ich denke, das passiert nicht, weil die Do-Notation im falschen Kontext arbeitet, d. H. Eff anstelle von Maybe. In Haskell würde ich das mit dem 'MaybeT'-Monodentrafo angehen. Gibt es in Idris etwas Ähnliches? Erlauben mir abhängige Typen, etwas sauberer zu machen? – marcosh

+0

Fügen Sie den 'EXCEPTION()' Effekt hinzu. Habe 'nothing' call' raise() ', da ist bereits ein Handler basierend auf Maybe definiert, der funktioniert, egal was du anhäufst. –