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
で失われているため、本来のFoo t
と新しいFoo t0
には一致しません。ここでのコンテキストは十分ではないのですか? f = Foobar g
が正しい結果を得られない場合がありますか?
N.B .: ScopedTypeVariables
と明示的なタイプシグネチャは役立たないようです。 a ~ Foo t
という制約を追加し、代わりにg
のタイプとしてa
を使用すると、Foobar g
にも機能しません。
多くのように見えます。ambiguous type error when using type families, and STV is not helping。私はProxy
を使うと考えましたが、この場合、GHCはそれを理解できるはずです。
「Fooobar(g :: Foo t)」を追加しても、 't'の情報は' Foo t'ですでに失われているでしょうか? 'Foo'を注入しないで、' Proxy'を使わないで 't ::'を意味するところで、 'g :: Foo t'の使用を強制する別の方法はありますか? –
@NicolasMattiaはい、私の最後の編集を見てください。 – chi
これは素晴らしい答えです、ありがとうございます。私はGHC 8の新しい拡張を見て、何ができるかを見ていきます。 1つの軽微なコメントは、私は最後の行で注入性を意味するとは思わない(GHCが注入性のないt〜t0を理解することがポイントである)。 –