型をロジックとして解釈する1つの方法は、戻り値型の値の存在条件としてです。だから、f :: a -> [a]
型の値が存在する場合、定理たちはa
、型の値が存在します[a]
。関数の実装は命題の証明です。
詳細は次のとおりです。
基本的に、データコンストラクターを使用すると、合計や積(ORおよびAND)と同様のものを作成できますが、複数のバリアントを使用でき、型を名前で特別に "タグ付け"して、それを区別できます(名前などList
)。
また、再帰的に構築することもできます。 a、命題 [ a ] 方程式の解と見なすことができます
x (a )⟺⊤ ∨ (∧ X ())
Agdaに表示されるのと同様のGADTスタイルの疑似コードを使用してListの定義を記述すると、状況が少し明確になります。
data List : Type -> Type where
Nil : ∀ a . List a
Cons : ∀ a . a -> List a -> List a
これにより、2つのものが得られList
ます。の命題の公理として機能するコンストラクター(または関数)と、それらをパターンマッチングまたは分解する公理です。
大まかに言えば、それはロジックに以下の公理を導入します:
- どんな命題でも a、 [ a ] 保持します。
- もし a 保持し、 [ a ] 保持し、 [ a ] 保持する
- もし [ a ] 保持し、その後 ⊤ 保持、または ∧ [ A ] 保持します。
ロジックとして解釈すると、これらは常に役に立たない ⊤ 保持している、そこを分解してもあまり有用な情報は得られない
量指定子またはより強力な型拡張(GADT、型ファミリー、依存型など)がないと、興味深いことを実際に証明できないことがわかります。そのため、標準のHaskell型をロジックとして解釈することについてあまり理解していません。 。