问题描述
foo :: X -> Y -> Z
我进行了两次单独的计算以获取类型为X
和Y
的变量,但是它们可能会失败,所以我使用Maybe
calc1 :: A -> Maybe X
calc2 :: B -> Maybe Y
现在我不确定如何使用monad操作来获得所需的行为
safe_foo :: Maybe X -> Maybe Y -> Maybe Z
safe_foo nothing _ = nothing
safe_foo _ nothing = nothing
safe_foo (Just x) (Just y) = Just (foo x y)
什么是最好的方法?
解决方法
您只需要liftA2,它被定义为Applicative
类型类的一部分。
safe_foo = liftA2 foo
或者,以“应用样式”:
safe_foo mx my = foo <$> mx <*> my
,
您可以将monad与do
一起使用
safe_foo mx my = do -- BTW,we underscore_case is unconventional in Haskell,x <- mx -- preferrably use camelCase instead
y <- my
return $ foo x y
...或者简化和简化
safe_foo mx my = mx >>= (<$>my) . foo
但是实际上您不需要Monad
,Applicative
就足够了。
safe_foo = liftA2 foo
或直接使用calc函数,
foo <$> calc1 a <*> calc2 b