あなたが求めているものはできませんが、全く同じようなものがあります。証明には型レベルブーリアンのケース分析が必要ですが、そのようなイベントが発生するようなデータはありません。修正は、シングルトンを介してそのような情報だけを含めることです。
最初に、idemp
のタイプがやや難読化されています。 a ~ b
という制約は、同じものを2度だけ命名します。次typechecks:
idemq :: p (Or b b) -> p b
idemq = undefined
idemp :: a ~ b => p (Or a b) -> p a
idemp = idemq
(あなたはt
はa
が含まれていない制約a ~ t
を持っている場合、それは例外がinstance
宣言であるa
ためt
を代用するのは良いことだ:。何もマッチしますインスタンスヘッドでa
したがって、たとえその事が明らかにt
になっていなくてもインスタンスは起動しますが、私は逃げ出します。)
私が請求するidemq
は、b
に関する有用な情報がないため、定義できません。入手可能なデータはp
で、唯一のデータは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つであるという証拠が必要です。私たちはそのためたちがBooly b
を知っている場合、我々はb
が何であるかを教えてくれるケース分析を行うことができます
data Booly :: Bool -> * where
Truey :: Booly True
Falsey :: Booly False
を歌いましょう。それぞれの場合はうまくいくでしょう。ここでは、p b
を抽象化するのではなく、PolyKinds
で定義された等価タイプを使用して、ファクトをパックする方法について説明します。
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
は、暗黙のうちにtypを修正するのに必要なOr b b ~ b
の証拠を詰めています。 es。
これらのシングルトン値を明示的にスリングしたくない場合は、kosmikusが示唆するように、それらを辞書で非表示にして、必要なときにそれらを抽出することができます。
Richard EisenbergとStephanie Weirichは、これらのファミリとクラスを作成するTemplate Haskellライブラリを用意しています。 SHEは、あまりにもそれらを構築し、あなたはpi b :: Bool.
がforall b :: Bool. Booly b ->
に展開
orIdem pi b :: Bool. Or b b :=: b
orIdem {True} = Refl
orIdem {False} = Refl
を書き込むことができますすることができます。
しかし、それはそのようなpalaverです。だから私のギャングは、実際にpi
をHaskellに追加することに取り組んでいます。ノンパラメトリック量子(forall
と->
とは異なります)は、Haskellのタイプと用語の言語の間の重要でない交差点のものでインスタンス化できます。このpi
には、引数がデフォルトで非表示になっている「暗黙の」変種もあります。 2つはそれぞれシングルトンファミリとクラスを使用することに対応していますが、追加のキットを入手するためにデータ型を3回以上定義する必要はありません。
合計型の理論では、実行時にブールb
の余分なコピーを渡すためにはではなく、である必要があります。事実は、b
は、データがp (Or b b)
からp b
に転送される可能性があるという証明を行うためだけに使用されています。必ずしもデータを転送する必要はありません。実行時にバインダーの下で計算するわけではないので、方程式の不正確な証明を調理する方法がないので、証明コンポーネントとそれを配信するb
のコピーを消去することができます。 Randy Pollackが言っているように、強正規化微積分で働くことについての最良の事は、物事を正規化する必要はありません。
私の疑惑は、あなたがハスケルでこれをプロキシにいくつかの追加の制約なしに行うことができないことです。あなたが何らかの形で 'proxy a'型の値を構築する必要があり、' proxy'を構築する方法やその中の値を変更する方法がわからないということを伝えましょう。 'proxy 'の制約は受け入れられますか? –
「タイプレベルの論理和の証明」は素晴らしい質問タイトルです。 – AndrewC
@ JohnL:制約を使用してそれを行う方法は明らかです。しかし、それが証明ではなく、仮定に相当することを証明する定理の文脈では。 –