あなたが求めていることは不可能ですが、代わりにかなり似たようなことができるかもしれません. 証明には型レベルのブール値のケース分析が必要なため不可能ですが、そのようなイベントを発生させるためのデータがありません。修正は、シングルトンを介してそのような情報を含めることです。
idemp
まず、タイプ forが少し難読化されていることに注意してください。制約a ~ b
は、同じものを 2 回指定するだけです。次の型チェック:
idemq :: p (Or b b) -> p b
idemq = undefined
idemp :: a ~ b => p (Or a b) -> p a
idemp = idemq
( を含まない制約a ~ t
がある場合、通常は を代用するのが良いでしょう。例外は宣言にあります:インスタンスの先頭にある an は何にでも一致するため、そのものが明らかに になっていなくても、インスタンスは起動します。しかし、私は余談。)t
a
t
a
instance
a
t
idemq
について有用な情報がないため、定義できないと主張しb
ます。利用可能な唯一のデータは inhabit p
-of-something であり、何が何であるかはわかりませんp
。
の場合によって推論する必要がありb
ます。一般的な再帰型ファミリでは、どちらTrue
でもない型レベルのブール値を定義できることに注意してFalse
ください。スイッチをオンにするとUndecidableInstances
、定義できます
type family Loop (b :: Bool) :: Bool
type instance Loop True = Loop False
type instance Loop False = Loop True
したがって、またはにLoop True
還元することはできず、局所的にさらに悪いことに、それを示す方法はありません。True
False
Or (Loop True) (Loop True) ~ Loop True -- this ain't so
それから抜け出す方法はありません。b
私たちのが何らかの形で値を計算する適切に動作するブール値の 1 つであるという実行時の証拠が必要です。だから歌おう
data Booly :: Bool -> * where
Truey :: Booly True
Falsey :: Booly False
が分かればBooly b
、事例分析を行うことができ、何が何でb
あるかがわかります。その後、各ケースはうまく処理されます。PolyKinds
uses を抽象化するのではなく、 で定義された等価型を使用して事実をまとめる方法を次に示しますp b
。
data (:=:) a b where
Refl :: a :=: a
私たちの重要な事実は、今では明白に述べられ、証明されています。
orIdem :: Booly b -> Or b b :=: b
orIdem Truey = Refl
orIdem Falsey = Refl
そして、厳密なケース分析によってこの事実を展開できます。
idemp :: Booly b -> p (Or b b) -> p b
idemp b p = case orIdem b of Refl -> p
事例分析は厳密でなければなりません。証拠が馬鹿げた嘘ではなく、型を修正するために必要なRefl
証拠だけを黙って詰め込んでいる善良な正直者であることを確認するためです。Or b b ~ b
これらすべてのシングルトン値を明示的にスリングしたくない場合は、kosmikus が示唆するように、それらを辞書に隠して、必要なときに抽出することができます。
Richard Eisenberg と Stephanie Weirich には、これらのファミリとクラスをミリングする Template Haskell ライブラリがあります。彼女もそれらを構築することができ、あなたは書くことができます
orIdem pi b :: Bool. Or b b :=: b
orIdem {True} = Refl
orIdem {False} = Refl
にpi b :: Bool.
展開されforall b :: Bool. Booly b ->
ます。
しかし、それはとてもつまらないものです。そのため、私のギャングは Haskell に real を追加することに取り組んでいます。これは、Haskell の型言語と用語言語の間の重要な共通部分でインスタンス化できるノンパラメトリック量指定子 ( and とはpi
異なります) です。これには、引数がデフォルトで隠されている「暗黙の」バリアントもある可能性があります。2 つはそれぞれシングルトン ファミリとクラスの使用に対応しますが、追加のキットを取得するためにデータ型を 3 回定義する必要はありません。forall
->
pi
完全な型理論では、実行時にブール値の余分なコピーを渡す必要がないことに言及する価値があるかもしれません。b
問題は、データが から にb
転送される可能性があることを証明するためだけに使用されp (Or b b)
、p b
必ずしも転送されるデータを作成するためではないということです。実行時にバインダーの下で計算しないため、方程式の不正な証明を作成する方法はありません。したがって、証明コンポーネントを消去して、そのコピーb
を配信することができます。Randy Pollack が言うように、強力に正規化する微積分で作業することの最も良い点は、物事を正規化する必要がないことです。