我发现自己想使用all
单子函数。在我看来,这并不是真的很漂亮:
f :: Monad m => a -> m Bool
g :: Monad m => [a] -> m Int
g xs = do cnd <- liftM (all (== True)) $ mapM f xs
if cnd
then return 42
else return 0
有更好的方法吗?
如果您import Control.Applicative
和Data.Bool
(如果使用base >= 4.7
)一起使用,则可以将其写为
g xs = bool 0 42 <$> and <$> mapM f xs
-- Or equivalently
-- g xs = bool 0 42 . and <$> mapM f xs
-- g = fmap (bool 0 42 . and) . mapM f
但是我认为这不会给您带来很多好处。相反,您也可以将其拉到return
之外if-then-else
:
g xs = do cnd <- and <$> mapM f xs
return $ if cnd then 42 else 0
甚至
g xs = do ys <- mapM f xs
return $ if and ys then 42 else 0
我认为大多数人会更愿意看到最后两个版本中的一个,尽管对于使用“ if and foo then bar else baz”的英语使用者来说,最后一个版本看起来有点奇怪
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句