2017-10-19 19 views
3

Tenir compte de ce programme:Idris - question de l'évaluation paresseuse

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 

depuis le côté droit de >>== est déclaré retours paresseux et !(nothing "a")Nothing, je me attends à ce que le côté droit de >>== ne serait pas évalué.

Mais en réalité, il ne s'évalué, et je ne comprends pas pourquoi ...

De façon plus générale, je suis en train de concaténer Eff calculs qui renvoient peut-être et d'arrêter l'exécution quand je reçois le premier Nothing

Répondre

0

Desugar the! notation.

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

Il est clair que "a", "b" et "fin" seront tous imprimés, mais func ne peuvent pas être évalués.

Je pense que vous devrez définir >>== pour agir sur (certaines) Eff valeurs, plutôt que directement sur Maybe s.

HTH

+0

Ce que je fait comme est que le calcul s'arrête après 'rien « a »', de sorte que ' « b »' est jamais imprimé. Je suppose que cela n'arrive pas parce que la notation 'do' fonctionne dans le mauvais contexte, c'est-à-dire' Eff' au lieu de 'Maybe'. Dans Haskell, j'aborderais cela en utilisant le transformateur de monade 'MaybeT', y a-t-il quelque chose de similaire dans Idris? Est-ce que les types dépendants me permettent de faire quelque chose de plus propre? – marcosh

+0

Ajoutez l'effet 'EXCEPTION()'. N'avez rien à appeler 'raise()', il y a déjà un gestionnaire basé sur Maybe defined qui fonctionne peu importe ce que vous avez. –