2017-06-26 2 views
2

J'ai écrit un code monadique en utilisant un monade de lecteur et je me demande s'il y a une façon d'écrire en utilisant le do notation:Sugaring Code monadique du lecteur monade

m = Map.fromList [("This","is"), ("is","the"), ("the","secret")] 
f x m = fromMaybe "default" $ Map.lookup x m 

r :: String -> Reader (Map String String) String) 
r x = reader $ \m1 -> f x m1 

runReader ((r "This") >>= r >>= r) m 
-- "secret" 

Maintenant, comment voulez-vous écrire la dernière déclaration faire la notation.

J'ai le sentiment que tous les « monades élargies » à l'aide runX fonctions ne prêtent pas vraiment à faire la notation.

+2

'runReader (do {s1 <- r "Ce", s2 <- r s1; r s2}) m'-t-il. Bien que pour ce genre de choses, vous soyez probablement plus intéressé par l'opérateur '> =>' et newtype 'Kleisli'. Par exemple, 'runReader ((r> => r> => r)" This ") m' fait la même chose. – Alec

Répondre

3

Vous pouvez faire

runReader threeRs m where 
    threeRs = do 
    a <- r "This" 
    b <- r a 
    r b 

bien que je ne recommanderais pas cela. Dans ce cas, l'opérateur bind (>>=) correspond assez bien au chaînage réel.

à mon humble avis la notation do est très utile lorsque le séquençage des opérations monadiques où tous les résultats ne sont nécessaires, les résultats doivent être combinés ou fonctions pures sont utilisées inbetween. Voir aussi Should do-notation be avoided in Haskell?

2

Le do -notation est juste:

runReader r' m 
    where r' = do 
     x <- r "This" 
     y <- r x 
     z <- r y 
     return z 

Mais en utilisant (>>=) fait il sens beaucoup plus.