消除 lambda 最直接的方法是使用liftA2;就是你写的代码
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 f x y = pure f <*> x <*> y
foldl (liftA2 (+)) (Just 0) [Just 1, Just 2]
那么对于如何传播错误,我们有几个选择。这段代码表明任何Nothing 都会导致完全失败。我们可以像@bhekilr 建议的使用sequence 那样分两步来做到这一点。
sum <$> sequence [Just 1, Just 2] sum <$> sequence [Just 1, Nothing]
Just (sum [1,2]) sum <$> Nothing
Just 3 Nothing
我们还可以使用(+) 在值上诱导Monoid 的事实,以便“忽略”Nothings。最字面意思是
import Data.Monoid
getSum $ foldMap (maybe mempty Sum) [Just 1, Just 2, Nothing]
-- equivalent to, but faster than
getSum . mconcat . map (maybe mempty Sum) $ [Just 1, Just 2, Nothing]
getSum . mconcat $ [Sum 1, Sum 2, Sum 0]
3
但我们也可以使用Data.Monoid中的catMaybe分两步完成
sum . catMaybes $ [Just 1, Just 2, Nothing]
sum [1, 2]
3