[英]Haskell generic typeclass with list
我有一個像這樣定義的類,所以foo
采用泛型類型並返回一個Integer:
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推斷出類型,並做了類似這樣的事情:
foo [False,True] - > foo False + foo True - > 10 + 10 = 20
我看過幾本書並閱讀了關於多態性和類型類的知識,包括了解大好的Haskell! 但仍然無法繞過如何解決這個問題?
你需要說列表必須包含Foo
值:
instance Foo a => Foo [a] where
foo (h:t) = foo h + foo t
foo [] = 0
當h
是Foo
實例時,您只能調用foo h
,因此您需要為[a]
限定類型類,以便它僅適用於Foo
實例的列表。
否則,例如,如果你有[Int]
, foo h
意味着你試圖在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
記住,調用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
->
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.