Не может поднять несколько параметров в монаде - PullRequest
0 голосов
/ 15 февраля 2019

Здравствуйте, я пытаюсь сделать следующее:

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]) (++) - (зная, что (++) может быть применен к любому типу - будучи monoid).

В этом случае я получаю следующее исключение:

* 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]) (++)

1 Ответ

0 голосов
/ 15 февраля 2019

f требует в качестве аргумента first функция с монадой.При первой попытке вы вообще не проходили функцию;во втором вы передаете (++) в качестве аргумента last .

Следующее работает нормально:

> 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]
...