sab*_*uma 10 monads haskell map maybe
Data.Map和Data.IntMap中的查找函数当前返回包含在带有类型签名的Maybe中的值
lookup :: Ord k => k -> Map k a -> Maybe a
Run Code Online (Sandbox Code Playgroud)
它曾经有更普遍的类型
lookup :: (Monad m, Ord k) => k -> Map k a -> m a
Run Code Online (Sandbox Code Playgroud)
我意识到前者可能会减少额外类型规范的需要,但后者会使它更加通用,并允许在列表推导中使用查找.有没有办法模仿新版本的这种行为,还是我必须使用旧版本的库?
Don*_*art 19
后者会使它更加通用,并允许在列表推导中使用查找
后者也更不安全,因为大多数monad类定义失败error
.也就是说,在Map中找不到元素的常见情况是大多数monad的程序终止错误.这一点,再加上推断错误类型上下文的可能性增加,意味着我们现在倾向于劝阻"monadic fail return"风格.
有没有办法模仿新版本的这种行为
确实有!简单地将Maybe a提升为Monad a,就像这样:
lift :: Monad m => Maybe a -> m a
lift Nothing = fail "you die now"
lift (Just a) = return a
Run Code Online (Sandbox Code Playgroud)
现在你可以写,例如 lift . lookup
唐的lift
转换Maybe
的元素,其一般Monad
的同行,所以也许它应该被命名convert
或者generalize
什么;-)
如果您只想lookup
在列表推导和其他实现a的monad中使用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"
对于 list monad 的具体情况,最简单的解决方案是使用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"]
Run Code Online (Sandbox Code Playgroud)