为什么将数据类型添加为类型声明的约束会导致匹配错误而不是更正确的错误?

B. *_*Zen 4 haskell typeclass

或者,换句话说,是否需要添加如下所述的约束?

工作代码,函数f的最小类型声明:

data ZeroPositive = Zero | Positive Int deriving Show
f :: [Int] -> [ZeroPositive]
f [] = []
f (0:xs) = Zero:(f xs)
f (x:xs) = (Positive x):(f xs)
main = putStrLn . show $ f [0,2]
Run Code Online (Sandbox Code Playgroud)

结果:

[Zero,Positive 2]
Run Code Online (Sandbox Code Playgroud)

破坏的代码与无用的约束ZeroPositive:

data ZeroPositive = Zero | Positive Int deriving Show
f :: ZeroPositive => [Int] -> [ZeroPositive]
f [] = []
f (0:xs) = Zero:(f xs)
f (x:xs) = (Positive x):(f xs)
main = putStrLn . show $ f [0,2]
Run Code Online (Sandbox Code Playgroud)

结果:

  99.hs:3:7:
  Couldn't match expected type `ZeroPositive' with actual type `[t0]'
  In the pattern: []
  In an equation for `f': f [] = []

  99.hs:3:12:
  Couldn't match expected type `[Int] -> [ZeroPositive]'
          with actual type `[a0]'
  In the expression: []
  In an equation for `f': f [] = []

  ...

  99.hs:6:32:
  Couldn't match expected type `ZeroPositive' with actual type `[t0]'
  In the first argument of `f', namely `[0, 2]'
  In the second argument of `($)', namely `f [0, 2]'
  In the expression: putStrLn . show $ f [0, 2]
Run Code Online (Sandbox Code Playgroud)

Ørj*_*sen 5

应该是一个错误,因为它ZeroPositive是一种数据类型,而不是一个类,因此不允许作为约束.

然而,你得到的奇怪的错误信息,是因为你使用的是一个有bug的旧GHC版本(GHC 7.4,如果我没记错GHC 7.6,那个获得ConstraintKinds扩展的一般工作,因此制作=>->允许更多相同语法中的位置使得它被=>视为->将实际数据类型而不是约束放在其左侧.