题
在Data.Map和Data.IntMap查找功能目前返回值包裹在也许带 类型签名
lookup :: Ord k => k -> Map k a -> Maybe a
它用于具有更一般的类型
lookup :: (Monad m, Ord k) => k -> Map k a -> m a
我意识到前者可能减少额外的类型规范的需要,而后者将使它更通用,并允许查找在列表解析中使用。有什么办法来模仿这种行为与较新的版本,否则我将不得不使用图书馆的旧版本?
解决方案
Don的lift
转换Maybe
的元素,它们的一般Monad
对应,所以也许它应该被命名convert
或generalize
或东西; - )
如果你只是想用lookup
主要集中在列表解析和其他单子实现一个fail
,你也可以使用模式匹配失败的映射到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"
其他提示
后者将使它更一般和允许查找,以在列表解析中使用
后者也是更不安全的,因为大多数单子类的定义失败,因为error
。也就是说,没有找到在地图元素的常见的情况是大多数的单子程序终止错误。也就是说,加上错误类型上下文的可能性增加被推断装置我们倾向于现在劝阻“单子失败返回”风格。
有什么办法来模仿这种行为与新版本
的确有!简单地抬起也许到单子一个,像这样:
lift :: Monad m => Maybe a -> m a
lift Nothing = fail "you die now"
lift (Just a) = return a
和现在可以写,例如lift . lookup
有关列表单子的特定情况下,最简单的解决方案是使用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"]
不隶属于 StackOverflow