带有列表

时间:2018-01-25 11:43:56

标签: haskell generics typeclass

我有一个像这样定义的类,因此foo采用泛型类型并返回一个Integer:

class Foo a where
  foo :: a -> Integer

并定义了几个实例,因此它适用于BoolChar类型:

instance Foo Bool where
  foo _ = 10

instance Foo Char where
  foo _ = 20

如果我现在想要为具有泛型类型的列表添加实例,我希望这样做:

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

然而,这是错误的。根据我目前的理解,我想假设Haskell推断类型并执行类似的操作:

  

foo [False,True] - > foo False + foo True - > 10 + 10 = 20

我看过几本书并阅读了关于多态性和类型类的内容,包括了解大好的Haskell!但仍然无法解决如何解决这个问题?

2 个答案:

答案 0 :(得分:6)

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

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

foo hh实例时,您只能调用Foo,因此您需要限定[a]的类型类,以便它仅适用于{的列表{1}}个实例。

否则,例如,如果您有Foo,则[Int]意味着您尝试在foo h值上调用foo,但Int未针对该类型定义。

通过foo的上述实现,您可以得到预期的结果:

[a]

答案 1 :(得分:3)

你忘了基本情况:

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

请注意,调用foo ts 意味着我们在第二个元素上调用foo。我们实际上以递归方式调用我们定义的函数(粗体为foo),因此这将继续在列表的元素上调用foo,直到列表用完为止,在这种情况下,将使用基本案例foo [] = 0

所以它会评估:

   foo (False : True : [])
-> foo False + foo (True : [])
-> 20 + foo (True : [])
-> 20 + foo True + foo []
-> 20 + 20 + foo []
-> 20 + 20 + 0
-> 20 + 20
-> 40
->