我可以用一个空的case写一些不可能的东西,例如,用Decision
来使用它。
{-# LANGUAGE DataKinds, EmptyCase, LambdaCase, TypeOperators #-}
import Data.Type.Equality
import Data.Void
data X = X1 | X2
f :: X1 :~: X2 -> Void
f = \case {}
-- or
-- f x = case x of {}
有没有办法不使用case
,直接对参数进行模式匹配来编写等效的参数?
f :: X1 :~: X2 -> Void
f ???
3条答案
按热度按时间dtcbnfnu1#
好吧,你可以使用一个可怕的CPP黑客:
但是,如果您正在寻找一个使用纯Haskell语法的解决方案,我敢肯定答案是否定的。与空case不同,您不能使用模式语法定义
f
,而至少没有一个模式。而且,没有GHC认为是无人居住类型术语的密码的模式。(即使有,也没有语法允许您定义没有右侧的f pat
。)jchrr9hc2#
这里是一个使用模式同义词的尝试。它并不完全令人满意,可能不是你真正想要的。它只在移动
\case{}
远离你的眼睛。我们仍然需要在某些点上使用absurd
。另一种方法是利用Template Haskell。
b1payxdu3#
我想如果你想模仿这一点,最简单的方法就是类似于在评论中贴出一个答案:
然而,这是懒惰:
而空格则是严格的:
因此,更好的替代方法是使用
seq
:或者
BangPatterns
:因此,你可以直接写
f = impossible
,这对我来说似乎很好。(a
上的量词在逻辑上更像是“for any”,而不是“for all”。)当然,你可以抛出一些更具描述性的东西,而不是进入一个无限循环,以防这种情况实际上不是不可能的-error "the impossible was possible after all"
。这也适用于
void
包中Void
的老式定义data Void = Void !Void
或newtype Void = Void Void
。