Les monades peuvent faire beaucoup de choses étonnantes et folles. Elles peuvent créer des variables qui contiennent une superposition de valeurs. Elles peuvent vous permettre d'accéder à des données du futur avant de les calculer. Elles peuvent vous permettre d'écrire des mises à jour destructives, mais pas vraiment. Et puis la monade continuation vous permet de briser l'esprit des gens ! Habituellement le vôtre. ;-)
Mais voici un défi : Pouvez-vous créer une monade qui peut être interrompu ?
data Pause s x
instance Monad (Pause s)
mutate :: (s -> s) -> Pause s ()
yield :: Pause s ()
step :: s -> Pause s () -> (s, Maybe (Pause s ()))
Le site Pause
est une sorte de monade d'état (donc mutate
avec la sémantique évidente). Normalement, une monade comme celle-ci possède une sorte de fonction "run", qui exécute le calcul et vous renvoie l'état final. Mais Pause
est différent : il fournit un step
qui exécute le calcul jusqu'à ce qu'elle appelle la fonction magique yield
fonction. Ici, le calcul est mis en pause, renvoyant à l'appelant suffisamment d'informations pour reprendre le calcul plus tard.
Pour plus d'efficacité : Permettez à l'appelant de modifier l'état entre step
appels. (Les signatures de type ci-dessus devraient le permettre, par exemple).
Cas d'utilisation : Il est souvent facile d'écrire du code qui fait quelque chose de complexe, mais c'est un véritable casse-tête de le transformer pour qu'il puisse aussi être utilisé pour d'autres applications. sortie les états intermédiaires de son fonctionnement. Si vous voulez que l'utilisateur puisse changement quelque chose à mi-chemin de l'exécution, les choses deviennent très vite complexes.
Idées de mise en œuvre :
-
Évidemment il peut être fait avec des threads, des verrous et des
IO
. Mais pouvons-nous faire mieux ? ;-) -
Quelque chose d'insensé avec une monade de continuation ?
-
Peut-être une sorte de monade d'écriture, où
yield
enregistre juste l'état actuel, et ensuite nous pouvons "prétendre" àstep
en itérant sur les états du journal. (Évidemment, cela exclut la modification de l'état entre les étapes, puisque nous ne faisons pas vraiment de "pause" maintenant).