Haskell无法创建TypeClass的实例

WuH*_*ted 3 haskell types instance typeclass

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

我有以下代码,我试图说:1)分支可以在其第一个位置保持任何类型,2)创建一个类线性,它取线性的东西,并返回一个数字3)使分支成为线性的实例,如果分支持有的第一件事是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
Run Code Online (Sandbox Code Playgroud)

我得到错误:无法推断(a~a1)来自实例声明绑定的上下文(Num a).....

有谁知道如何在Haskell中表达我想说的是什么?

sep*_*p2k 8

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

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

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

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