簡體   English   中英

Haskell如何為類型類的實例選擇方法?

[英]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的思維過程是這樣的:

  1. 它試圖找出(5 :: Int, 5 :: Int)(Int, Int)MyShow實例
  2. 然后它找到實例MyShow a => MyShow (a, b)
  3. 由於這統一,( a => ab => a )它選擇了這個實例。
  4. 它檢查,以確保a ,在這種情況下Int ,也是一個實例MyShow ,它是。 注意:選中實例進行此檢查。
  5. myShow (5 :: Int, 5 :: Int)調用元組的myShow並成為myShowTuple (5 :: Int, 5 :: Int)
    • 它不調用myShowTuple因為它有類型(a, b)而在元組的情況下, a(a, b)所以myShowTuple的類型((a, b) ,c)顯然不匹配。
  6. 這具有這樣的類型MyShow a => (a, b) -> String)並且由於a在這種情況下具有的類型Int的Haskell可解決此到Int的實例MyShow
  7. 它運行適當的myShowTuple
  8. 你得到"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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM