[英]How does Haskell choose methods for instances of type classes?
我試圖理解為什么即使沒有FlexibleInstances
Pragma,Haskell的show
也會處理不同於整數列表的字符列表。
通讀了Show
的文檔,我意識到我並不真正理解Haskell如何為類型類的實例選擇方法。
請考慮以下代碼:
class MyShow a where
myShow :: a -> String
myShowList :: [a] -> String
myShowTuple :: (a, b) -> String
myShowList xs = "Default List Implementation"
myShowTuple t = "Default Tuple Implementation"
instance MyShow Char where
myShow c = "One Char"
myShowList xs = "List of Chars"
myShowTuple t = "Char Tuple"
instance MyShow Int where
myShow n = "One Int"
myShowList xs = "List of Integers"
myShowTuple t = "Int Tuple"
instance MyShow Float where
myShow n = show n
instance (MyShow a) => MyShow [a] where
myShow = myShowList
instance (MyShow a) => MyShow (a, b) where
myShowTuple t = "foo"
myShow = myShowTuple
現在如果我打電話,例如
myShow (5::Int,5::Int)
我希望Haskell能夠'哦, myShow
得到一個元組作為一個論點。 讓我們看看我必須打電話給哪個實施。 並選擇最后一個會導致"foo"
。 顯然,事實並非如此。 哈斯克爾似乎看元組(即該類型的內容a
),並決定調用相應的方法,造成"Int Tuple"
。
為什么是這樣?
當你編寫myShow (5::Int, 5::Int)
,Haskell 會說“哦,myShow有一個元組作為參數。讓我們看看我必須調用哪個實現。” 它確實選擇了最后一個,即myShow = myShowTuple
。 但這並不意味着結果將是“foo”。 這意味着調用myShow (5::Int, 5::Int)
的結果與調用myShowTuple (5 :: Int, 5 :: Int)
的結果相同。
所以現在Haskell必須決定它必須調用哪個版本的myShowTuple
。 由於myShowTuple
類型為MyShow a => (a, b) -> String
,因此在myShowTuple
第二行上定義的myShowTuple
版本的類型為MyShow a => ((a, c), b) -> String
,所以一個人不合適。 第17行定義的那個類型(Int, b) -> String
,因此一個適合。 這就是被選中的那個。
Haskell的思維過程是這樣的:
(5 :: Int, 5 :: Int)
或(Int, Int)
的MyShow
實例 MyShow a => MyShow (a, b)
a
=> a
和b
=> a
)它選擇了這個實例。 a
,在這種情況下Int
,也是一個實例MyShow
,它是。 注意:選中實例后會進行此檢查。 myShow (5 :: Int, 5 :: Int)
調用元組的myShow
並成為myShowTuple (5 :: Int, 5 :: Int)
myShowTuple
因為它有類型(a, b)
而在元組的情況下, a
是(a, b)
所以myShowTuple
的類型((a, b) ,c)
顯然不匹配。 MyShow a => (a, b) -> String)
並且由於a
在這種情況下具有的類型Int
的Haskell可解決此到Int
的實例MyShow
myShowTuple
"Int Tuple"
只是一個旁注,如果這是Show
的實際實現,你需要為myShowTuple
這樣的myShowTuple
myShowTuple :: MyShow b => (a, b) -> String
否則你無法實際格式化b
,畢竟是任何類型。
這會
instance (MyShow a) => MyShow (a, b) where
...
成
instance (MyShow a, MyShow b) => MyShow (a, b) where
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.