Haskell 无法在单子中提升多个参数

Haskell 无法在单子中提升多个参数,haskell,monads,lift,monoids,Haskell,Monads,Lift,Monoids,您好,我正在尝试执行以下操作: module MyMonad where f::(Monad m),=>m (a->b->c)->m a -> m b -> m c f mf ma mb= ma >>= \a -> mb >>= \b -> mf >>= \c -> return (c a b) 然后像这样使用它: f (Just 3) (Just 4) 我得

您好,我正在尝试执行以下操作:

module MyMonad where
f::(Monad m),=>m (a->b->c)->m a -> m b -> m c
f mf ma mb=
    ma >>= \a ->
    mb >>= \b ->
    mf >>= \c ->
        return (c a b) 
然后像这样使用它:

f (Just 3) (Just 4) 
我得到以下错误:

* Non type-variable argument in the constraint: Num (a -> b -> c)
      (Use FlexibleContexts to permit this)
    * When checking the inferred type
        it :: forall a b c.
              (Num a, Num (a -> b -> c)) =>
              Maybe b -> Maybe c
我不知道如何放置多个类型约束,因此我尝试如下: f Just[3]Just[4]+-knowing++可以应用于任何类型-作为幺半群。 在这种情况下,我得到以下异常:

* Couldn't match expected type `Maybe b0'
                  with actual type `[a1] -> [a1] -> [a1]'
    * Probable cause: `(++)' is applied to too few arguments
      In the third argument of `f', namely `(++)'
      In the expression: f (Just [3]) (Left [3]) (++)
      In an equation for `it': it = f (Just [3]) (Left [3]) (++)
f需要一个单子包装函数作为第一个参数。在第一次尝试中,您根本没有通过该函数;在第二个参数中,传递++作为最后一个参数

以下工作很好:

> f (Just (++)) (Just [3]) (Just [4])
Just [3,4]
liftM2和更一般的liftA2已经做了一些与您想要的非常相似的事情

> import Control.Monad (liftM2)
> liftM2 (++) (Just [3]) (Just [4])
Just [3,4]
> import Control.Applicative (liftA2)
> liftA2 (++) (Just [3]) (Just [4])
Just [3,4]
f需要一个单子包装函数作为第一个参数。在第一次尝试中,您根本没有通过该函数;在第二个参数中,传递++作为最后一个参数

以下工作很好:

> f (Just (++)) (Just [3]) (Just [4])
Just [3,4]
liftM2和更一般的liftA2已经做了一些与您想要的非常相似的事情

> import Control.Monad (liftM2)
> liftM2 (++) (Just [3]) (Just [4])
Just [3,4]
> import Control.Applicative (liftA2)
> liftA2 (++) (Just [3]) (Just [4])
Just [3,4]

列表类型是幺半群;也许a不是。您仍然需要使用lift++将其应用于Maybe列表;一份申请书就足够了。f::Applicative g=>ga->b->c->ga->gb->gc,其中f gf ga gb=gf ga gb。列表类型为幺半群;也许a不是。您仍然需要使用lift++将其应用于Maybe列表;一份申请书就足够了。f::Applicative g=>ga->b->c->ga->gb->gc,f gf ga gb=gf ga gb。但是它不能与不同类型的函子一起工作吗?像f Just++Just[3]Left[4]No;我认为这是问题中的一个输入错误。给定的类型要求始终使用相同的单子。哦,对不起,这是你的问题,所以不是打字错误。如果您想对来自两个不同Monad的值进行操作,您需要像Monad m1、Monad m2=>a->b->c->m1a->m2 b->这样的东西???。你必须决定结果将住在哪个单子里。但是,我不建议这样做。让调用者负责将[3]转换为a或b值,或将[4]转换为a或a值,并将函数绑定到单个monad。对于这一点,我会考虑使用LIFTA2++只是[3 ]只是[4 ],而不是手动提升+ +之前调用F.但它不能与不同类型的函子一起工作吗?像f Just++Just[3]Left[4]No;我认为这是问题中的一个输入错误。给定的类型要求始终使用相同的单子。哦,对不起,这是你的问题,所以不是打字错误。如果您想对来自两个不同Monad的值进行操作,您需要像Monad m1、Monad m2=>a->b->c->m1a->m2 b->这样的东西???。你必须决定结果将住在哪个单子里。但是,我不建议这样做。让调用者负责将[3]转换为a或b值,或将[4]转换为a或a值,并将函数绑定到单个monad。对于这一点,我会考虑使用LIFTA2++只是[3 ]只是[4 ],而不是手动提升+ +之前调用F。