あなたがする必要はありません:EmptyCase
言語拡張を使用して、このステートメントは実際に証明可能です。ここで自己完結型のファイルがそれを実証している:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE EmptyCase #-}
module ZeroNeqOne where
data (==) a b where
Refl :: a == a
data Nat where
Z :: Nat
S :: Nat -> Nat
zeroNeqOne :: Z == S Z -> a
zeroNeqOne p = case p of {}
を考えると、あなたがコメントで定理証明を話していたこと、それは私が考えるようになったし、それは我々がかなりのような小さなゲームCoqのユーザーを再生することができ判明:使用します型レベルの対角関数。 Cf。 JF Monin's Proof Trick: Small inversions。今回は、拡張子TypeFamilies
を使用します。矛盾を破棄する考え方a == b
は、a
と表示されたときに些細な目標を証明し、b
と表示されたときに不可能な目標を証明するよう求めるタイプレベル関数を使用することです。そして、不可能なものに平凡な結果を輸送するために平等の証明を使用します。 `zeroNeqOne :: Z == Z - > A`、それはshouldnの」:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
module ZeroNeqOneDiag where
import Data.Void
data (==) a b where
Refl :: a == a
subst :: a == b -> p a -> p b
subst Refl pa = pa
data Nat where
Z :: Nat
S :: Nat -> Nat
type family Diag (n :: Nat) :: * where
Diag 'Z =()
Diag ('S n) = Void
newtype Diagonal n = Diagonal { runDiagonal :: Diag n }
zeroNeqOneDiag :: 'Z == 'S 'Z -> Void
zeroNeqOneDiag p = runDiagonal $ subst p (Diagonal())
は、私は、しかし、その後、次のようにもコンパイルされることを試してみましたt( 'ghci ZeroNeqOne.hs -XDataKinds -fwarn-incomplete-patterns -Werror'のようにコンパイルします)。 –
[カバレッジチェッカーのバグ](https://ghc.haskell.org/trac/ghc/ticket/10746)のようです。したがって、空の場合には注意が必要です。それは、あなたが要求したような定義を伴わずにタイプシグネチャを持つよりも危険ではないと言われています。 – gallais
希望は、これに付随するバインディングを使用せずにこれを達成できること、またパターンがあるときにコンパイル時エラーが発生することでした。とにかく深刻なものをやっている時には、定理の証明者を優先すると思います。しかし、ありがとう! –