monad tranformers et l'empilage de plusieurs monades
-
22-09-2019 - |
Question
Je fonction f
avec f :: [a] -> StateT Int Reader b [c]
signature et f'
avec f' :: a -> StateT Int Reader b [c]
signature
Le calcul de f (très simplifiée) ressemble à ce que:
f [] = return []
f (s:st) = f' s >>= \x ->
f st >>= \y ->
return $ ...
Et à la place du ... Je voudrais revenir la partie [c]
de x
++
la partie [c]
de y
avec l'étoffe de monade enroulé autour.
Est-il possible d'y parvenir sans déballer manuellement x
et y
et de mettre manuellement le résultat à nouveau ensemble? Ai-je besoin d'une liste monade au fond de ma pile de monade pour obtenir le code simple? Le lecteur Monad est évidemment pas une instance de la classe MonadPlus.
La solution
Je ne comprends pas ce que vous entendez par déballant x
et y
.
J'aurais la dernière ligne comme
return (x ++ y)
Est-ce que je comprends mal ce que vous voulez?
Autres conseils
Vous pouvez également définir simplement
f = fmap concat . mapM f'
(mapM f' xs
produit une valeur de type m [[c]]
, où xs :: [a]
et m = StateT Int (Reader b)
, puis fmap concat
concatène les listes "à l'intérieur de la monade").
Les deux f' s
et f st
sont des valeurs dans une monade, à savoir StateT Int Reader b
. Donc, vous avez déjà x :: [c]
et y :: [c]
et vous avez juste besoin d'écrire return (x ++ y)
, comme l'a dit Dave Hinton.