型のレベルリストの先頭に何かがあるかどうかを判断する型ファミリがあります。データファミリがある場合の型(in)の等価性
type family AtHead x xs where
AtHead x (x ': xs) = True
AtHead y (x ': xs) = False
この結果を表すシングルトンを構築したいと思います。これは単純な型のリストでうまく動作します。
data Booly b where
Truey :: Booly True
Falsey :: Booly False
test1 :: Booly (AtHead Char [Char, Int])
test1 = Truey
test2 :: Booly (AtHead Int [Char, Int])
test2 = Falsey
しかし、私は本当にがやりたいするインデックス付きdata family
のメンバーのリストについては、この値を構築しています。 (実際には、私は彼らのタイプに基づいてID
秒の異質リストのうちの要素を予測しようとしている。)
data family ID a
data User = User
newtype instance ID User = UserId Int
我々が探しているID
は、リストの先頭にあるとき、これは動作します。
test3 :: Booly (AtHead (ID User) [ID User, Char])
test3 = Truey
しかし、それ以外は失敗します。
test4 :: Booly (AtHead (ID User) [Int, ID User])
test4 = Falsey
Couldn't match type ‘AtHead (ID User) '[Int, ID User]’
with ‘'False’
Expected type: Booly (AtHead (ID User) '[Int, ID User])
Actual type: Booly 'False
In the expression: Falsey
In an equation for ‘test4’: test4 = Falsey
AtHead (ID User) '[Int, ID User]
'False
で統一しません。 GHCは、とInt
は、data family
であるにもかかわらず、ID
が等しくないと判断することには消極的であると思われます(したがって、(減少するもの)はID User
です)。
制約ソルバーが受け入れるものと受け入れないものの私の直感はむしろ弱いです。私はこれをコンパイルしなければならないと感じます。誰も私のコードが型チェックしない理由を説明することはできますか? GHCを受け入れて、おそらく定理を証明して、それを受け止める方法がありますか?
私はGHCが注射データ群であまり良くないと知っています。ラッパーを作成することがある'newtype ID 'a = ID'(ID a)'です。 – luqui
GHCのバグかもしれないように私には思われます。これらのタイプは「確実に離れている」べきである(GHC専門用語)。 –
[報告されました](https://ghc.haskell.org/trac/ghc/ticket/10910)。 –