[英]HasResolution typeclass
我只是查找了HasResolution
類型類 ,它有一個方法, resolution
聲明如下:
class HasResolution a where
...
resolution :: p a -> Integer
我不明白上述聲明中的p
。 它來自哪里,它意味着什么?
這只是一個代理人。
如果你有
class HasResolution a where
resolution :: Integer
你會在,因為沒有辦法讓編譯器永遠推斷其中的情況下獲得罵得HasResolution
你想,當你調用resolution
。 具體來說, resolution :: HasResolution a => Integer
,其中a
出現在左邊但不在右邊,所以你永遠不能推斷a
。
所以,一個解決方案是
class HasResolution a where
resolution :: a -> Integer
和resolution
的文件會說它不是要檢查a
; 它只是讓編譯器找出要選擇的實例。 你將它用作resolution (undefined :: a)
。 然后,另一個解決方案出現
data Proxy a = Proxy
class HasResolution a where
resolution :: Proxy a -> Integer
Proxy
不提供resolution
信息; 它再次存在,僅用於編譯器推斷出a
是什么。 它比原始resolution
更好,因為resolution
實際上無法檢查它的參數,因此Integer
實際上與類型相關聯,而不是與resolution
的參數相關聯。 它稍差(或更好,取決於你問的是誰),因為用法是更冗長的resolution (Proxy :: Proxy a)
(你不能只使用undefined
因為實現可能在Proxy
上模式匹配)。
這演變成了
class HasResolution a where
resolution :: p a -> Integer
這意味着您不僅僅局限於Proxy
,這意味着如果您有例如[a]
在范圍內,您可以將其傳遞給resolution
而不會產生大量冗長,同時保持與剛剛使用的代碼的兼容性Proxy
。 同樣, resolution
的第一個參數僅供編譯器使用。 它對實際實現沒有任何意義。 您只需使用它來選擇所需的HasResolution
實例。
Proxy
最終變得如此普遍, GHC.Exts
得到了一個新成員: Proxy#
。 Proxy#
沒有運行時表示,因此與Proxy
(或上述多態p
技巧)不同,它不會造成性能損失。 然而, Proxy#
受到這樣的事實的影響,即它的類型是forall k. k -> TYPE (TupleRep '[])
forall k. k -> TYPE (TupleRep '[])
。 如果不居住在*
像所有其他的“乖巧”的類型,它不能參與多態p
伎倆。
class HasResolution a where
resolution :: Proxy# a -> Integer
第一個解決方案是相當過時的,盡管你有時會看到例子。 第二個和第三個相當常見,第四個被最新的解決方案很快取代,即啟用-XTypeApplications -XAllowAmbiguousTypes
並且只有
class HasResolution a where
resolution :: Integer
再次。 -XAllowAmbiguousTypes
消除錯誤, -XTypeApplications
允許您在呼叫站點指定a
作為resolution @a
。 這不能用在需要一定程度向后兼容的代碼中,但是在需要新GHC的庫中你會看到更多,並且可以承受不具備兼容性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.