Haskell - 禁用伴随绑定检查 haskell

Haskell - disable accompanying binding check haskell

我不想在 Haskell 中禁用检查伴随绑定的功能。

我想这样做的原因是能够实现反证法。以下类型签名没有任何绑定,也不应该有。

zeroDoesNotEqualOne :: Refl Z (S Z) -> Bottom

类型 Refl Z (S Z) 没有居民,因此应该没有绑定。

在上面的代码片段中,类型表示您所期望的类型,例如 S Z 是 1 的 Peano 自然数,而 Refl 只有一个 Refl a a[=17 类型的居民=]

你不需要:使用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 用户非常喜欢的小游戏:在类型级别使用对角线函数。比照。 JF 莫宁 Proof Trick: Small inversions。这次我们将使用 TypeFamilies 扩展名。丢弃矛盾的 a == b 的想法是使用一个类型级函数,它会要求我们在 a 出现时证明一个微不足道的目标,而在 b 出现时要求我们证明一个不可能的目标。然后使用相等性证明将平凡的结果传输到不可能的结果:

{-# 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 ())