我是haskell编程的新手,我想知道为什么会出现错误
Non type-variable argument in the constraint: Eq Int
(Use FlexibleContexts to permit this)
当我尝试定义像这样的函数时
union :: (Eq (Int)) => [Int] -> [Int] -> [Int]
答案 0 :(得分:5)
存在类型类约束以限制函数使用的类型。例如,如果您的类型a -> a -> a
是一个需要能够处理任何类型的参数的函数(只要两个参数具有相同的类型)。如果将其更改为Eq a => a -> a -> a
,现在只需要使用实现Eq
的类型的参数,允许您对参数使用==
。
在您的情况下,您有一个[Int] -> [Int] -> [Int]
类型的函数。它已经受到限制:该函数专门用于[Int]
类型的两个参数 - 不允许其他类型。
因此,将其限制为仅实现Int
的{{1}}类型是没有意义的,因为Eq
已经是一种特定类型。因此,类型应为Int
,您仍然可以使用[Int] -> [Int] -> [Int]
,因为==
确实实现了Int
。
答案 1 :(得分:5)
你在这里写道:
Eq Int => ...
但是这没用,我们肯定知道Int
是Eq
类型类的实例,说明它是多余的。
通常只会在其中编写带有类型变量的类型约束,例如:
union :: Eq a => [a] -> [a] -> [a]
确实需要编写这种类型约束。在这种情况下,我们可以union
使用每个 a
,因为Eq a
成立。这保留给定a ~ Int
,但后者我们也可以将其用于a ~ Char
,a ~ Maybe Int
等。
我们的想法是,如果您编写Eq a
,则可以将(==) :: Eq a => a -> a -> Bool
和(/=) :: Eq a => a -> a -> Bool
函数与a
类型的表达式一起使用。但是,您只使用Int
s,因此我们确信我们可以做到这一点。
虽然从理论的角度来看,写Eq Int
并不是错误,但它更像是非感性的#34;。