這個標題確實不是很具描述性,但我不知道如何用簡短的標題來描述這個。我會很感激任何建議!從一系列較小的實例推斷一般類型實例?
我將要提出我的問題:)
的一個非常簡化的版本,所以我有一個類型類
class Known f a where
known :: f a
這被認爲是能夠產生一個給定的規範建設鍵入某個索引,對於使用GADT和其他東西很有用。我給出this的簡化版本以及相關部分。
所以這是很明顯的Proxy
一個實例:
instance Known Proxy a where
known = Proxy
,我們可以使用:
> known :: Proxy Monad
Proxy
但也有一個爲this HList-like type一個實例:
data Prod f :: [k] -> * where
PNil :: Prod f '[]
(:<) :: f a -> Prod f as -> Prod f (a ': as)
infixr 5 (:<)
凡Prod f '[a,b,c]
會大致相當於一個(f a, f b, f c)
元組。相同的函子,不同的類型。
編寫實例體面簡單:
instance Known (Prod f) '[] where
known = PNil
instance (Known f a, Known (Prod f) as) => Known (Prod f) (a ': as) where
known = known :< known
其中一期工程得非常好:(假定顯示實例)
> known :: Prod Proxy '[1,2,3]
Proxy :< Proxy :< Proxy :< PNil
但是,我在哪裏,我需要做的情況下所有as
上的「多態」功能......但GHC不喜歡它。
asProds :: forall as. Proxy as -> Prod Proxy as
asProds _ = known :: Prod Proxy as
它與此錯誤出現:
No instance for (Known (Prod f) as)
arising from a use of 'known'
我的猜測是說,GHC無法顯示,將有一個實例它將搭載將爲任何as
工作,或者,它沒有爲該實例構建known
的策略。
作爲一個人我知道這是事實,但是有什麼辦法可以讓這個工作?這些實例都在「範圍內」並且可用......但我怎麼能告訴GHC如何以滿意的方式構建它?
啊。不幸的是,避免這種限制是我首先經歷這個問題的原因。但!我的問題最初是因爲我需要爲我所有的存在指定'(Applicative(Foo ns),Foldable(Foo ns))'等等,我認爲只有這樣才能擺脫這一切。但我現在看到,我可以用'已知'約束替換所有這些各種約束。沒有避免這種限制,但現在只需要一個全部更清潔,謝謝! –
@JustinL。你也可以使用[約束同義詞](https://downloads.haskell.org/~ghc/7.8.4/docs/html/users_guide/constraint-kind.html):'type Known ns =(Applicative(Foo ns) ,可摺疊(Foo ns),...)'。 –
@AlexeyRomanov它仍然感覺非常臨時和un-haskell給我。我可能會拋出一堆實例,這些實例只有非常罕見/不常見和晦澀的用法,這些用法在實際的數據構造函數中沒有任何業務屬於這種類型......它與那些晦澀難懂的類沒有任何關係所有。每次我寫一個新的實例時,我都必須添加類和重複的工作。 –