Haskell中的多输入单函数

问题描述

我有这样的功能

foo :: X -> Y -> Z

我进行了两次单独的计算以获取类型为XY的变量,但是它们可能会失败,所以我使用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

但是实际上您不需要MonadApplicative就足够了。

safe_foo = liftA2 foo

或直接使用calc函数,

   foo <$> calc1 a <*> calc2 b