3

我试图理解这个问题中给出的关于可变参数函数的示例,并尝试从以下位置修改代码:

class SumRes r where 
    sumOf :: Integer -> r

instance SumRes Integer where
    sumOf = id

instance (Integral a, SumRes r) => SumRes (a -> r) where
    sumOf x = sumOf . (x +) . toInteger

对此:

class SumRes r where 
    sumOf :: Int -> r

instance SumRes Int where
    sumOf = id

instance (SumRes r) => SumRes (Int -> r) where
    sumOf x = sumOf . (x +) 

我得到一个Illegal instance declaration for SumRes (Int -> r). 有人可以解释这意味着什么以及我反对的限制是什么?

4

2 回答 2

5

您只是遇到了 Haskell 标准的限制。标准 Haskell 只允许一组受限的实例声明。特别是所有实例都必须是“简单的”,因为它们是应用于零个或多个类型变量的类型。

这意味着您可以拥有或Int的实例。但是,您不能拥有类似. 这就是您在这里遇到的问题:您的实例应用了一个类型 ( )以及一个变量。MaybeMaybe aMaybe Int->Int

然而,尽管这种行为不在标准中,但它仍然有意义,因此您可以通过扩展启用它。就是FlexibleInstances这样,明显的警告是您的代码不再是标准的 Haskell。

于 2013-04-27T18:03:41.873 回答
3

在标准的 Haskell 中,实例头(实例中类名之后的部分)必须是类型构造函数和不同类型变量的形式。T a1 a2 .. anTai

编译器会抱怨,因为您的实例头是(->) Int r,并且Int不是类型变量。

在 GHC 中,可以使用扩展来解除此限制FlexibleInstances,这样做的唯一真正缺点是可能缺乏可移植性。

于 2013-04-27T18:04:01.800 回答