3

我是 Haskell 的新手,正在尝试使用实例创建一个类。

我有以下代码,我想说的是:1)Branch 可以在其第一个位置保存任何类型,2)创建一个 Linear 类,它采用线性事物并返回一个数字 3)如果Branch 拥有的第一件事是 Num 类的一部分。

data Branch a = Branch a Integer deriving (Show, Eq)

class Linear l where
    length :: (Num a) => l -> a

instance (Num a) => Linear (Branch a) where
    length (Branch len _) = len

我收到错误消息:无法从实例声明绑定的上下文 (Num a) 中推断出 (a ~ a1) ...

有人知道如何在 Haskell 中表达我想说的话吗?

4

1 回答 1

8

您的类定义说length必须能够返回用户请求的任何 Num 类型。所以如果用户想要一个 Integer,length 方法必须给他一个 Integer。如果他想要一个 Int 或 Double ,长度也必须给他。

但是,您在实例声明中提供的长度函数不符合要求。例如,当您在 a 上调​​用 length 时Branch Integer,length 将返回一个Integer。即使用户要求它也不会返回一个Int或一个。Double

使您的代码工作的一种方法是使用多参数类型类来定义具有两个参数的线性,其中第二种类型是length应该返回的数字类型。然后你可以有一个Linear (Branch a) a. 您可能还想使用 Functional Dependencies 扩展使其更有用。除了第二个类型参数,您还可以使用 Type Families 扩展来实现类似的效果。

另一种方法是将实例声明更改为 requireIntegral a而不是Num a然后fromIntegral len用作返回值。这会将存储在分支中的整数类型转换为用户请求的任何数字类型。当然,需要注意的是,您使用非整数数值进行分支不会是Linear这种方式的实例。

于 2012-07-19T03:31:44.917 回答