簡體   English   中英

HasResolution類型類

[英]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.

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