[英]GHC stuck due to UndecidableSuperClasses - expected behaviour or bug?
以下代碼片段使GHC(經8.6.2和8.4.4檢查)在編譯期間卡住了:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
import GHC.Exts (Constraint)
data T = T
type family F t (c :: * -> Constraint) :: Constraint
type instance F T c = c T
class F t C => C t where
t :: C T => t
t = undefined
我認為它卡住,因為t
GHC試圖找到CT
,從而導致FTC
它通過家庭類型擴展F
回CT
,這是它一直在尋找(無限循環)。
我想從理論上說,GHC可以說它已經達到了自己對CT
追求,而任何依賴於它的東西都可以遞歸地工作,還是我誤會了?
旁注:在我偶然發現此行為的真實示例中,通過用Data.Constraint.Dict
代替UndecidableSuperClasses
,我能夠實現我想要的目標而不會陷入編譯器。
UndecidableSuperClasses
不作實例解析懶惰。 編譯器仍將盡可能擴展超類約束。 我相信實例字典中指向超類字典的字段是嚴格的 ,GHC實際上在編譯時將它們固定下來。 這與UndecidableInstances
相反,后者允許延遲(一點)對待實例約束 。
deriving instance Show (f (Fix f)) => Show (Fix f)
會很好。 在為例如Show (Fix Maybe)
解析實例時,GHC將看到它需要Show (Maybe (Fix Maybe))
。 然后,它看到它需要Show (Fix Maybe)
(當前正在解決),並感謝UndecidableInstances
接受它。
UndecidableSuperClases
所做的所有事情都是禁用確保擴展不會循環的檢查。 埃德·克梅特 ( Ed Kmett)演講開始時的內容不多 ,他描述了“達到固定點”的過程。
考慮一個工作示例(從Data.Constraint.Forall
):
type family Skolem (p :: k -> Constraint) :: k
class p (Skolem p) => Forall (p :: k -> Constraint)
GHC僅接受UndecidableSuperclasses
接受。 為什么? 因為它對約束可能意味着什么一無所知。 據其所知, p (Skolem p)
可能會減少為Forall p
。 那實際上可能會發生!
class Forall P => P x
-- This definition loops the type checker
foo :: P x => x
foo = undefined
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.