Question

La fonction de recherche dans Data.Map et Data.IntMap actuellement des valeurs de retour enveloppé dans Peut-être avec la signature de type

lookup  :: Ord  k => k -> Map  k a -> Maybe  a

Il l'habitude d'avoir le type plus général de

lookup  :: (Monad  m, Ord  k) => k -> Map  k a -> m a

Je me rends compte l'ancien probablement réduit le besoin de spécification de type supplémentaire, mais celui-ci serait beaucoup plus générale et permettre recherche à utiliser dans la liste compréhensions. Est-il possible d'imiter ce comportement avec la version plus récente, ou devrais-je utiliser une ancienne version de la bibliothèque?

Était-ce utile?

La solution

lift de Don convertit les éléments de la Maybe à leurs homologues de Monad général, donc peut-être qu'il devrait être nommé convert ou generalize ou quelque chose; -)

Si vous voulez juste utiliser lookup principalement dans la liste et compréhensions autres monades qui mettent en œuvre un fail, vous pouvez également utiliser la cartographie de l'échec de correspondance de motif à fail:

Prelude> [ v | Just v <- return $ lookup "hi" [("ho","silver")] ]
[]
Prelude> [ v | Just v <- return $ lookup "ho" [("ho","silver")] ]
["silver"]

Prelude> do Just v <- return $ lookup "hi" [("ho","silver")] ; print v
*** Exception: user error (Pattern match failure in do expression at <interactive>:1:3-8)
Prelude> do Just v <- return $ lookup "ho" [("ho","silver")] ; print v
"silver"

Autres conseils

  

ce dernier rendrait beaucoup plus générale et permettre recherche à utiliser dans la liste compréhensions

Ce dernier est aussi plus dangereuse, car la majorité des classes de monades définissent comme error échouent. C'est, le cas fréquent de ne pas trouver un élément dans la carte est une erreur de terminaison de programme pour la plupart des monades. Cela, couplé à la probabilité accrue du contexte de mauvais type étant inférée, des moyens, nous avons tendance à décourager le style « échec Monadique retour » maintenant.

  

Est-il possible d'imiter ce comportement avec la nouvelle version

Il y a en effet! Il suffit de soulever Peut-être un dans Monad un, comme suit:

lift :: Monad m => Maybe a -> m a
lift Nothing  = fail "you die now"
lift (Just a) = return a

Et vous pouvez maintenant écrire, par exemple lift . lookup

Pour le cas spécifique de la monade liste, la solution la plus simple est d'utiliser maybeToList:

Prelude> :m +Data.Maybe -- Note: Use "import Data.Maybe" in a program file

Data.Maybe> [ v | v <- maybeToList $ lookup "hi" [("ho","silver")] ]
[]
Data.Maybe> [ v | v <- maybeToList $ lookup "ho" [("ho","silver")] ]
["silver"]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top