Question

Quelles sont les différences entre le style passent continuation (cps) et monades.

Était-ce utile?

La solution

Comme mentionné dans L'essence de la programmation fonctionnelle :

  

Programmation avec monades rappelle fortement le style de passage continuation (CPS), et cet article explore la relation entre les deux. En un sens, ils sont équivalents: CPS se présente comme un cas particulier d'une monade, et tout monade peuvent être incorporés dans CPS en changeant le type de réponse. Mais l'approche monadique apporte des informations supplémentaires et permet un meilleur niveau de contrôle.

Ce document est tout à fait rigoureux, et en fait, il ne se développe pas tout à fait sur la relation entre CPS et monades. Ici, je tente de donner un exemple informel, mais illustrative:

(Note:. Ci-dessous un comprendre de Monad d'un débutant (moi-même), mais après l'avoir écrite ne semble ressembler à un de ces la réponse des utilisateurs haut de rep S'il vous plaît ne prenez avec une tonne de sel)

Considérez la monade Maybe classique

-- I don't use the do notation to make it 
-- look similar to foo below

bar :: Maybe Int
bar =
    Just 5 >>= \x ->
    Just 4 >>= \y ->
    return $ x + y

bar' :: Maybe Int
bar' =
    Just 5 >>= \x ->
    Nothing >>= \_ ->
    return $ x

GHCi> bar
Just 9
GHCi> bar'
Nothing

Ainsi, le calcul s'arrête dès que Nothing se rencontre, rien de nouveau ici. L'essai Let pour imiter un tel comportement à l'aide monadique CPS:

Voici notre fonction add à la vanille à l'aide CPS. Nous utilisons tous Int ici au lieu du type de données pour le rendre algébriques plus facile:

add :: Int -> Int -> (Int -> Int) -> Int
add x y k = k (x+y)

GHCi> add 3 4 id
7

Remarquez comment il est semblable à une monade

foo :: Int
foo =
    add 1 2 $ \x -> -- 3
    add x 4 $ \y -> -- 7
    add y 5 $ \z -> -- 12
    z

GHCi> foo
12

OK. Supposons que nous voulons que le calcul soit plafonné à 10. C'est, quel que soit le calcul doit arrêter quand l'étape suivante entraînerait une valeur supérieure à 10. C'est un peu comme dire « Peut-être un calcul doit cesser et Nothing de retour dès que toute valeur dans la chaîne est Nothing). nous allons voir comment nous pouvons le faire en écrivant un « transformateur CPS »

cap10 :: (Int -> Int) -> (Int -> Int)
cap10 k = \x ->
    if x <= 10 
    then 
        let x' = k x in 
        if x' <= 10 then x' else x
    else x

foo' :: Int
foo' =
    add 1 2 $ cap10 $ \x -> -- 3
    add x 4 $ cap10 $ \y -> -- 7
    add y 5 $ cap10 $ \z -> -- 12
    undefined

GHCi> foo'
7

Notez que la valeur de retour finale peut être undefined, mais qui est bien, parce que l'évaluation s'arrête à la 3ème étape (z).

On peut voir que cap10 « enveloppes » la continuation normale avec une certaine logique supplémentaire. Et ce qui est très proche de ce que monade -. Calculs de colle avec une certaine logique supplémentaire

go une étape de Let autre:

(>>==) :: ((Int -> Int) -> Int) -> (Int -> Int) -> Int
m >>== k = m $ cap10 k

foo'' :: Int
foo'' =
    add 1 2 >>== \x -> -- 3
    add x 4 >>== \y -> -- 7
    add y 5 >>== \z -> -- 12
    undefined

GCHi> foo''
7

Woa! Peut-être que nous venons d'inventer la monade Cap10!

Maintenant, si on regarde le code source de Cont , nous voyons que Cont est

newtype Cont r a = Cont { runCont :: (a -> r) -> r }

Le type de runCont est

Cont r a -> (a -> r) -> r
((a -> r) -> r) -> (a -> r) -> r

Ce qui aligne bien avec le type de notre >>==

Maintenant, pour répondre effectivement à la question

après avoir tapé tout cela, je relisez la question initiale. L'OP a demandé la "différence": P

Je suppose que la différence est CPS donne l'appelant plus de contrôle, où comme d'habitude le >>= dans une monade est entièrement contrôlée par l'auteur de la monade.

Autres conseils

Un document intéressant qui explore la question est "programmation fonctionnelle impératif", par Peyton Jones et Wadler.

Il est le papier qui introduit monade IO, et il a des comparaisons à d'autres approches, y compris CPS.

Les auteurs concluent:

  

monades sont plus puissants que continuations, mais seulement en raison des types! On ne sait pas si cela est seulement un artefact du système de type Hindley-Milner, ou si les types sont révélateurs d'une différence d'une importance fondamentale (notre propre intuition, c'est celle-ci -. Mais il est seulement une intuition)

Il n'y a pas de relation, donc la question fait autant de sens que de demander la différence entre la couleur bleue et Pluton.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top