與模糊型別的互動

假設你正在引入一類具有位元組大小的型別。

class SizeOf a where
    sizeOf::a -> Int

問題是對於該型別的每個值,大小應該是常量。我們實際上並不希望 sizeOf 函式依賴於 a,而只取決於它的型別。

沒有型別應用程式,我們得到的最佳解決方案是像這樣定義的 Proxy 型別

data Proxy a = Proxy

此型別的目的是攜帶型別資訊,但沒有值資訊。然後我們的類看起來像這樣

class SizeOf a where
    sizeOf::Proxy a -> Int

現在你可能想知道,為什麼不完全拋棄第一個引數?我們的函式的型別就是 sizeOf::Int,或者更準確,因為它是一個類的方法,sizeOf::SizeOf a => Int 或者更加明確的 sizeOf::forall a. SizeOf a => Int

問題是型別推斷。如果我在某處寫 sizeOf,推理演算法只知道我期待一個 Int。它不知道我想用什麼型別代替 a。因此,除非啟用了 {-# LANGUAGE AllowAmbiguousTypes #-} 擴充套件,否則編譯器會拒絕該定義。在這種情況下,定義編譯,它不能在沒有歧義錯誤的情況下在任何地方使用。

幸運的是,型別應用程式的引入節省了一天! 現在我們可以寫出 sizeOf @Int,明確地說 aInt。型別應用程式允許我們提供型別引數,即使它沒有出現在函式實際引數中