Haskell通用类型类与列表

tem*_*887 3 generics haskell typeclass

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

class Foo a where
  foo :: a -> Integer
Run Code Online (Sandbox Code Playgroud)

并定义了几个实例,以便它可以使用Bool和Char类型:

instance Foo Bool where
  foo _ = 10

instance Foo Char where
  foo _ = 20
Run Code Online (Sandbox Code Playgroud)

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

instance Foo [a] where
  foo (t:ts) = (foo t) + (foo ts)
Run Code Online (Sandbox Code Playgroud)

但是,这是错误的.根据我目前的理解,我想假设Haskell推断出类型,并做了类似这样的事情:

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

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

Mar*_*ann 6

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

instance Foo a => Foo [a] where
  foo (h:t) = foo h + foo t
  foo [] = 0
Run Code Online (Sandbox Code Playgroud)

你只能调用foo h时h是一个Foo实例,因此你需要限定型类[a],这样它仅适用于列表Foo实例.

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

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

Prelude> foo [True,False,True]
30
Prelude> foo [True,False,True,True]
40
Prelude> foo "foo"
60
Run Code Online (Sandbox Code Playgroud)