【发布时间】:2015-03-11 14:23:51
【问题描述】:
我发现自己处于想将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
有更好的™ 方法吗?
【问题讨论】:
-
首先,您不想使用
all (== True),而是使用and:-) -
确实,更一般地说:布尔值的相等比较几乎总是不必要的。如果不是
and,你仍然可以写all id。 -
您的实现没有正确“短路”:当纯计算短路时,它必须首先运行所有副作用。请参阅 monad-loops 包(及其兄弟,
allM)中的andM,以了解仅执行尽可能多的副作用以了解答案的版本。