(pas exactement une réponse à la question, mais connexe)
J'aime représenter les arbres d'un comme « ListT [] a
». (ListT
à partir du package List
dans hackage)
Ensuite, la réponse à cette question est simplement d'utiliser la fonction lastL
.
« Monad m => ListT m a
» est une liste contenant monadique s « a
de « où essayer d'obtenir l'élément suivant de la liste (qui peut savoir il n'y a pas un objet) est une action monadique dans » m
».
Un exemple d'utilisation pour ListT
- un programme qui lit les chiffres de l'utilisateur jusqu'à ce que l'utilisateur ne tapez pas de numéro et imprime la somme des chiffres après chaque entrée:
main =
execute . joinM . fmap print .
scanl (+) 0 .
fmap (fst . head) .
takeWhile (not . null) .
fmap reads .
joinM $ (repeat getLine :: ListT IO (IO String))
Où repeat
, scanl
et takeWhile
sont à partir de Data.List.Class
. Ils travaillent à la fois pour les listes régulières et les listes monadiques.
joinM :: List l => l (ItemM l a) -> l a -- (l = ListT IO, ItemM l = IO)
execute :: List l => l a -> ItemM l() -- consume the whole list and run its actions
Si vous êtes familier avec Python, itérateurs/générateurs python sont "ListT IO
" s.
Lorsque vous utilisez []
au lieu de IO
comme monade de la liste monadique, le résultat est un arbre. Pourquoi? Imaginez une liste où obtenir l'élément suivant est une action dans la liste monad - la liste monad signifie qu'il y a plusieurs options, donc il y a plusieurs "éléments suivants", ce qui en fait un arbre.
On peut construire des listes monadique soit avec des fonctions d'ordre supérieur (comme l'exemple ci-dessus), ou avec cons
, ou avec une notation python-générateur (avec yield
) à l'aide du transformateur GeneratorT
monade de l'emballage generator
dans hackage.
Avertissement: ListT
et GeneratorT
ne sont pas largement utilisés. Je les ai écrits et je ne connais pas d'autres utilisateurs sauf moi-même. Il y a plusieurs utilisateurs de ListT
équivalents, tels que celui du wiki Haskell, , et d'autres.
btw. Si vous aviez représenté l'arbre comme un "ListT [] un" (ListT du paquet List) alors "lastL" vous donnerait la liste des feuilles – yairchu
@yairchu: Que pensez-vous de http://www.haskell.org/ haskellwiki/ListT_done_right –
@alexey_r: c'est exactement la même chose, sauf que ce n'est pas dans Hackage, et ne vient pas avec des opérations de liste communes comme takeWhile etc. – yairchu