
computation m = …
ne peut pas fonctionner puisque computation à la type Reader … donc ne prend pas d’argument: tout est encapsulé dans la fonction runReader.
La magie provient de >>= qui, d’après ta définition, construit un nouveau reader en chaînant et décapsulant la première monade et la continuation (k): on applique la fonction contenue dans Reader avec (runReader m r), on produit une nouvelle monade en applicant k, on décapsule cette deuxième monade avec le descend appel à runReader. Tout ça est une fonction qui est encapsulée dans un Reader, donc qui devient le champ runReader de Reader.
Donc pour répondre à tes questions:
Q1: la fonction est un champ de Reader accessible avec runReader :: r -> a, donc tu extraies cette fonction du reader, et ensuite tu peux lui passer un argument.
Q2: cf. le chaînage ci-dessus. Le MyState est passé lors de la première invocation à runReader qui va dérouler la “computation”
Q3: pareil.
Le “principe”de reader et de beaucoup de code monadique est de construire des expressions, qui ne sont évaluées qu’au toplevel, en passant un argument à runXXX pour “démarrer” la chaîne de calcul. IO est un cas particulier qui démarre par l’appel à main. Tu ne peux pas (sauf magie) extraire une valeur de IO, alors que tu peux extraire une valeur (une fonction) depuis un Reader.
HTH
Arnaud
On 18 May 2014, at 12:04, Gautier DI FOLCO
2014-03-27 10:11 GMT+01:00 Gautier DI FOLCO
: 2014-03-27 6:07 GMT+01:00 Dan Popa : Hi,
Sorry for writing in english, I am not from France. Take a look here, please: http://www.haskell.org/haskellwiki/Modular_Monadic_Compilers_for_Programming...
The source at #3) on the above page is a code generator written using the State monad. The state monad is necessary because here it provides a sort of context, like a set of the global variables in imperative programming. And that is why we are using The State Monad, to simulate the use of a set of global (or local) variables, used to store values.
Especially in this example, the lenghts of the pieces of generated code are stored in order to compute the length of the biggers codes, when they are catenated, (glued together).
Other monads have specific use. Parser monad is used for glueing parsers, the list monad can simulate paralel computations and even backtracking (there is a backtracking monad too), the Maybe monad is used to make computations including Nothing in the set of values, etc.
Basically monadic capsules can be seen like Christmas Giftts containing compuations. And monadic operators have two kind of use: - return is a package maker, it creates a capsule, a package, like wrapping a gift - bind is something like: how to combine a function with a package. Open the package, compose functions, take care to produce an other package (or capsule).
Hoping it helps, Sincerely yours, Dan Popa
----- Forwarded Message ----- From: Gautier DI FOLCO
To: La liste Haskell Francophone Sent: Wednesday, March 26, 2014 12:10 PM Subject: [Haskell-fr] Éclaircissements sur les monades Bonjour,
Vaste sujet en perspective : les monades. Je pense avoir compris le principe des monades (être en mesure d'effectuer des actions sur une valeur au sein d'un contexte), en revanche il y a deux choses que je ne comprends pas : * La notion de contexte (ou de cadre de calcul) est un peu floue * Pourquoi est-ce que les monades sont aptes à contenir les effets de bords (j'ai lu effectful computations) et pas d'autres typeclass (comme Applicative).
Merci par avance pour vos réponses.
_______________________________________________ Haskell-fr mailing list Haskell-fr@haskell.org http://www.haskell.org/mailman/listinfo/haskell-fr
_______________________________________________ Haskell-fr mailing list Haskell-fr@haskell.org http://www.haskell.org/mailman/listinfo/haskell-fr
State Monads are clearer to me, thanks.
Bonjour à tous,
J'ai fais pas mal de progrès ces derniers temps (de manière globale) du coup il y a encore une zone d'ombre que j'aimerais éclaircir : comment les valeurs sont passées à une fonction ?
La question est vague, un exemple est de rigueur, j'ai ce code que je pense assez classique :
-- Generic
newtype Reader r a = Reader { runReader :: r -> a }
instance Monad (Reader r) where return a = Reader $ \_ -> a m >>= k = Reader $ \r -> runReader (k (runReader m r)) r
ask :: Reader a a ask = Reader id
asks :: (r -> a) -> Reader r a asks f = Reader f
local :: (r -> b) -> Reader b a -> Reader r a local f m = Reader $ runReader m . f
-- Specific
data MyState = MyState { foo :: String , bar :: Int } deriving (Show)
computation :: Reader MyState (Maybe String) computation = do n <- asks bar x <- asks foo if n > 0 then return (Just x) else return Nothing
example1 :: Maybe String example1 = runReader computation $ MyState "hello!" 1
example2 :: Maybe String example2 = runReader computation $ MyState "example!" 0
En gros j'ai deux soucis : comment runReader et asks fonctionnent ?
Voilà mon raisonnement :
Ça c'est notre but : runReader (asks bar) (MyState "example!" 0) :: Int runReader (asks bar) :: MyState -> Int => ok, on attends un MyState pour évaluer le tout
runReader :: Reader r a -> r -> a => pas ok : avec un Reader (qui contient une fonction r -> a) on sort cette fonction et on l'applique Question 1 : comment on applique cette fonction encapsulée ?
(asks bar) :: Reader MyState Int => pas ok : on attends un MyState pour sortir un Int Question 2 : comment ce MyState est "passé" et à quoi pour que ça sorte un Int ?
Jamais deux sans trois (même si je pense que répondre à la première question répondra mécaniquement aux deux autres). Question 3 : Pour computation, comment le Mystate est "passé" aux différents asks ? ou à l'envers, comment les asks savent où et quoi chercher ? (et comment l'appliquer) J'ai tenté le code suivant, sans succès : computation :: Reader MyState (Maybe String) computation m = do n <- asks bar m x <- asks foo m if n > 0 then return (Just x) else return Nothing
Merci par avance pour vos réponses et votre patience. _______________________________________________ Haskell-fr mailing list Haskell-fr@haskell.org http://www.haskell.org/mailman/listinfo/haskell-fr