具有列表的Haskell泛型类型类

具有列表的Haskell泛型类型类,haskell,generics,typeclass,Haskell,Generics,Typeclass,我有一个这样定义的类,foo采用泛型类型并返回一个整数: class Foo a where foo :: a -> Integer 定义了两个实例,因此它将与Bool和Char类型一起工作: instance Foo Bool where foo _ = 10 instance Foo Char where foo _ = 20 如果我现在想为一个具有泛型类型的列表添加一个实例,我想执行如下操作: instance Foo [a] where foo (t:ts)

我有一个这样定义的类,
foo
采用泛型类型并返回一个整数:

class Foo a where
  foo :: a -> Integer
定义了两个实例,因此它将与
Bool
Char
类型一起工作:

instance Foo Bool where
  foo _ = 10

instance Foo Char where
  foo _ = 20
如果我现在想为一个具有泛型类型的列表添加一个实例,我想执行如下操作:

instance Foo [a] where
  foo (t:ts) = (foo t) + (foo ts)
然而,这是错误的。根据我目前的理解,我想假设Haskell推断出了这些类型,并做了如下工作:

instance Foo [a] where
  foo (t:ts) = (foo t) + (foo ts)
foo[False,True]->foo-False+foo-True->10+10=20


我看了几本书,读了关于多态性和类型类的书,包括《学习Haskell For Great Good》!但是我仍然不知道如何解决这个问题?

你需要说列表必须包含
Foo
值:

instance Foo a => Foo [a] where
  foo (h:t) = foo h + foo t
  foo [] = 0
只有当
h
foo
实例时,才能调用
foo h
,因此需要将类型类限定为
[a]
,以便它仅适用于
foo
实例的列表

否则,例如,如果您有一个
[Int]
fooh
将意味着您将尝试对
Int
值调用
foo
,但没有为该类型定义
foo

通过对
[a]
的上述实现,您可以获得预期的结果:

Prelude> foo [True,False,True]
30
Prelude> foo [True,False,True,True]
40
Prelude> foo "foo"
60

您忘记了基本情况:

instance Foo a => Foo [a] where
  foo (t:ts) = foo t + foo ts
  foo [] = 0

为什么错了?你忘了基本情况,我确实忘了。当我试图解决主要问题时忽略了它。下一步是a
data AnyFoo=forall a。Foo a=>AnyFoo a
及其实例:)因此,在某种程度上,添加类约束会告诉它与Foo类中的类型相匹配,就像将类约束更改为Eq会告诉它在Eq类型类中查找匹配一样?@tem887我不确定您所说的查找匹配是什么意思,但如果该短语适用于您……)我认为,与类型
a
完全不受约束不同,类约束
fooa
声明只允许那些
a
类型也是
Foo
实例。更简单的定义是
Foo=sum。map foo是的,我知道。在本例中,ts是列表的尾部,即剩余的元素。我只想给出一个简单的例子,包括几个步骤:-)