无法将类型“Int”与“(a0, b0, c0)”匹配——“quickBatch”的触发器期望什么?

Couldn't match type ‘Int’ with ‘(a0, b0, c0)’ -- What does the trigger of `quickBatch` expect?

我想快速检查这个 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) 的类型才能编译?

checkers package:

查看 functorapplicativemonad 的签名

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

applicativemonad 相似:它们都需要三元组上的函子。您正在尝试使用 trigger::Sum Int Int。这意味着m~Sum Int,但错误告诉你Int(第二个)不能按照functor.[=22=的签名要求与(a,b,c)统一]