Haskell函数中Int的刚性用法

时间:2018-04-07 19:58:19

标签: haskell

我是haskell编程的新手,我想知道为什么会出现错误

Non type-variable argument in the constraint: Eq Int
      (Use FlexibleContexts to permit this)

当我尝试定义像这样的函数时

union :: (Eq (Int)) => [Int] -> [Int] -> [Int]

2 个答案:

答案 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 => ...

但是这没用,我们肯定知道IntEq类型类的实例,说明它是多余的。

通常只会在其中编写带有类型变量的类型约束,例如:

union :: Eq a => [a] -> [a] -> [a]

确实需要编写这种类型约束。在这种情况下,我们可以union使用每个 a,因为Eq a成立。这保留给定a ~ Int,但后者我们也可以将其用于a ~ Chara ~ Maybe Int等。

我们的想法是,如果您编写Eq a,则可以将(==) :: Eq a => a -> a -> Bool(/=) :: Eq a => a -> a -> Bool函数与a类型的表达式一起使用。但是,您只使用Int s,因此我们确信我们可以做到这一点。

虽然从理论的角度来看,写Eq Int并不是错误,但它更像是非感性的#34;。