以下代碼成功編譯,但在使用 GHC 9.2.3 時收到警告-Wredundant-constraints:
{-# LANGUAGE UndecidableInstances, FlexibleInstances #-}
class Functor f => C f where c :: f Int
instance (Functor f, Applicative f) => C f where c = pure 42
產生的警告:
test.hs:5:10: warning: [-Wredundant-constraints]
? Redundant constraint: Functor f
? In the instance declaration for ‘C f’
|
5 | instance (Functor f, Applicative f) => C f where c = pure 42
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
但是,如果我洗掉此約束,代碼將不再進行型別檢查:
test.hs:5:10: error:
? Could not deduce (Functor f)
arising from the superclasses of an instance declaration
from the context: Applicative f
bound by the instance declaration at test.hs:5:10-29
Possible fix:
add (Functor f) to the context of the instance declaration
? In the instance declaration for ‘C f’
|
5 | instance Applicative f => C f where c = pure 42
| ^^^^^^^^^^^^^^^^^^^^
這讓我很困惑。
這種約束真的是多余的,還是實際上有必要?
直覺上我會說它是多余的,因為它已經暗示了Applicative f!但是 GHC 要求有所不同,所以我不確定。
uj5u.com熱心網友回復:
因此,這Functor f看起來是多余的,但需要避免遞回超類導致字典包含實際上是底部的超類欄位的問題(即,當隱式訪問超類時,運行時的無限回圈)。
在編譯器源代碼compiler/GHC/Tc/TyCl/Instance.hs中的標題為“遞回超類”的部分中有一個解釋。結果是,在決議 . 的超類時Functor f,instance C f不允許使用 GHCApplicative f來決議Functor f,因為Applicative f它不是比C f. 通過要求只通過一系列更小的字典來決議超類,GHC 可以確保超類決議終止。
相反,Functor f對于這個類似的例子,實體定義中不需要:
class Functor f => C f x
instance (Applicative f) => C f Int
因為Applicative f是比 更小的字典C f Int,所以允許 GHC 使用它。
這里的“小詞典”是在特定的技術意義上使用的。字典的大小是其型別中建構式和變數的數量。因此,Applicative f大小為 2,而C f Int大小為 3。
這意味著這實際上Functor f 并不是多余的,因此警告是錯誤的。發出警告看起來像一個 GHC 錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/494280.html
