我遇到一個問題,其中GHC不能匹配Foo t
和Foo t0
,在那裏它肯定在我看來像t ~ t0
。這裏有一個小例子:曖昧類型與家族類型
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
data Foobar :: * -> * where
Foobar :: Foo t -> Foobar t
type family Foo a :: *
class Bar t where
f :: Foobar t
g :: Foo t
-- f = Foobar g
當取消註釋最後一行,GHC抱怨:
Couldn't match expected type ‘Foo t’ with actual type ‘Foo t0’
NB: ‘Foo’ is a type function, and may not be injective
The type variable ‘t0’ is ambiguous
Relevant bindings include f :: Foobar t (bound at test.hs:13:3)
In the first argument of ‘Foobar’, namely ‘g’
In the expression: Foobar g
我明白Foo
不是單射,但是從我的分析GHC是從來沒有要求拿出t
從Foo t
。看起來類型t
丟失在Foobar g
,所以它不能匹配inital Foo t
和新的Foo t0
。這裏的背景是不夠的嗎?我是否錯過f = Foobar g
無法產生正確結果的情況?
任何幫助表示讚賞!
N.B .: ScopedTypeVariables
和顯式類型簽名似乎沒有幫助。添加約束條件a ~ Foo t
並使用a
而不是Foobar g
中的g
類型也不起作用。
看起來很像:ambiguous type error when using type families, and STV is not helping。我考慮使用Proxy
,但我覺得在這種情況下,GHC應該能夠弄清楚。
因此,即使我添加'Foobar(g :: Foo t)','t'的信息已經在'Foo t'中丟失了,對吧?有沒有另一種方式強制使用'g :: Foo t',我的意思是't'而不使用'Foo'內射並且不使用'Proxy'? –
@NicolasMattia是的,看我最後的編輯。 – chi
這是一個很好的答案,謝謝。我將通過GHC 8的新擴展,看看可以做些什麼。一個小小的評論,我認爲你的意思並不是你的最後一行的注意力(關鍵在於GHC沒有注入地計算出「t〜t0」)。 –