Haskell 中柯里化的多输入单子函数

Multi-input monadic functions with currying in 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 类型的一部分 class。

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-functions,

   foo <$> calc1 a <*> calc2 b