Не удалось сопоставить тип «Int» с «(a0, b0, c0)» - что ожидает триггер `quickBatch`? - PullRequest
0 голосов
/ 31 октября 2018

Я хочу быстро проверить этот тип Sum, и я написал следующий код:

data Sum a b =
  First a
  | Second b
  deriving (Eq, Show)

instance Functor (Sum a) where
  fmap _ (First x) = First x
  fmap f (Second y) = Second (f y)

instance Applicative (Sum a) where
  pure = Second
  First x <*> _ = First x
  Second _ <*> First y = First y
  Second x <*> Second y = Second (x y)

instance Monad (Sum a) where
  return = pure
  First x >>= _ = First x
  Second x >>= f = f x

instance (Arbitrary a, Arbitrary b) => Arbitrary (Sum a b) where
  arbitrary = do
    x <- arbitrary
    y <- arbitrary
    frequency [(1, return $ First x)
              ,(1, return $ Second y)]

instance (Eq a, Eq b) => EqProp (Sum a b) where (=-=) = eq


main :: IO ()
main = do
  let trigger = undefined :: Sum Int Int
  quickBatch $ functor trigger
  quickBatch $ applicative trigger
  quickBatch $ monad trigger

Компилятор жалуется:

src/eithermonad.hs:100:24: error:
    • Couldn't match type ‘Int’ with ‘(a0, b0, c0)’
      Expected type: Sum Int (a0, b0, c0)
        Actual type: Sum Int Int
    • In the first argument of ‘functor’, namely ‘trigger’
      In the second argument of ‘($)’, namely ‘functor trigger’
      In a stmt of a 'do' block: quickBatch $ functor trigger
    |
100 |   quickBatch $ functor trigger
    |                        ^^^^^^^

src/eithermonad.hs:101:28: error:
    • Couldn't match type ‘Int’ with ‘(a1, b1, c1)’
      Expected type: Sum Int (a1, b1, c1)
        Actual type: Sum Int Int
    • In the first argument of ‘applicative’, namely ‘trigger’
      In the second argument of ‘($)’, namely ‘applicative trigger’
      In a stmt of a 'do' block: quickBatch $ applicative trigger
    |
101 |   quickBatch $ applicative trigger
    |                            ^^^^^^^

src/eithermonad.hs:102:22: error:
    • Couldn't match type ‘Int’ with ‘(a2, b2, c2)’
      Expected type: Sum Int (a2, b2, c2)
        Actual type: Sum Int Int
    • In the first argument of ‘monad’, namely ‘trigger’
      In the second argument of ‘($)’, namely ‘monad trigger’
      In a stmt of a 'do' block: quickBatch $ monad trigger
    |
102 |   quickBatch $ monad trigger
    |                      ^^^^^^^

И после того, как я сменил на

let trigger = undefined :: Sum (Int, String, Int) (Int, String, Int)

код можно скомпилировать и запустить функцию main.

Вопрос:

Что ожидает триггер quickBatch? Почему я должен изменить тип Int на что-то вроде (Int, String, Int), чтобы он компилировался?

1 Ответ

0 голосов
/ 31 октября 2018

Проверьте подписи functor, applicative и monad из пакета checkers :

functor :: (Functor m, ...) => m (a, b, c) -> TestBatch

applicative и monad похожи: все они требуют функтора над тройкой. Вы пытаетесь использовать trigger::Sum Int Int. Это означает m~Sum Int, но ошибка говорит вам, что Int (второй) нельзя объединить с (a,b,c), как того требует подпись functor.

...