Haskell 奇数ghc错误消息“1”;我的大脑刚刚爆炸了;?

Haskell 奇数ghc错误消息“1”;我的大脑刚刚爆炸了;?,haskell,gadt,arrows,Haskell,Gadt,Arrows,当我尝试以proc语法(使用Netwire和乙烯基)模式匹配GADT时: sceneRoot=proc inputs->do let(身份摄像机:&身份子对象)=输入 returnA-

当我尝试以
proc
语法(使用Netwire和乙烯基)模式匹配GADT时:

sceneRoot=proc inputs->do
let(身份摄像机:&身份子对象)=输入
returnA-<()(映射(目标绘制)子对象)。纯净的
我从ghc-7.6.3中得到了(相当奇怪的)编译器错误

My brain just exploded I can't handle pattern bindings for existential or GADT data constructors. Instead, use a case-expression, or do-notation, to unpack the constructor. In the pattern: Identity cam :& Identity childs 我的脑子爆炸了 我无法处理存在或GADT数据构造函数的模式绑定。 相反,使用case表达式或do表示法来解包构造函数。 在模式中:标识cam:&Identity childs 当我将模式放入
proc(…)
模式时,我会遇到类似的错误。为什么会这样?它是不健全的,还是只是没有实施?

考虑一下GADT

data S a where
  S :: Show a => S a
以及代码的执行

foo :: S a -> a -> String
foo s x = case s of
            S -> show x
在基于字典的Haskell实现中,人们期望值
s
携带一个类字典,并且
case
从所述字典中提取
show
函数,以便可以执行
show x

如果我们执行

foo undefined (\x::Int -> 4::Int)
我们有一个例外。在操作上,这是意料之中的,因为我们无法访问字典。 更一般地说,K->的
case(undefined::T)…
将产生错误,因为它强制计算
undefined
(前提是
T
不是
新类型

现在考虑代码(让我们假设它可以编译)

以及执行

bar undefined (\x::Int -> 4::Int)
这该怎么办?有人可能会说,它应该生成与
foo
相同的异常。如果是这样的话,参考透明度将意味着

let S = undefined :: S (Int->Int) in show (\x::Int -> 4::Int)
也会失败,但出现相同的异常。这意味着
let
正在计算
未定义的
表达式,与例如

let [] = undefined :: [Int] in 5
其计算结果为
5

实际上,
let
中的模式是惰性的:它们不强制表达式求值,这与
case
不同。这就是为什么

let (x,y) = undefined :: (Int,Char) in 5
成功计算为
5

如果在
e'
中需要一个
show
,人们可能想让
let S=e在e'
中评估
e
,但这感觉相当奇怪。同样,当计算
时,让S=e1;S=e2在show…
中不清楚是评估
e1
e2
,还是两者都评估

GHC目前选择用一条简单的规则禁止所有这些情况:在消除GADT时没有惰性模式。

考虑GADT

data S a where
  S :: Show a => S a
以及代码的执行

foo :: S a -> a -> String
foo s x = case s of
            S -> show x
在基于字典的Haskell实现中,人们期望值
s
携带一个类字典,并且
case
从所述字典中提取
show
函数,以便可以执行
show x

如果我们执行

foo undefined (\x::Int -> 4::Int)
我们有一个例外。在操作上,这是意料之中的,因为我们无法访问字典。 更一般地说,K->的
case(undefined::T)…
将产生错误,因为它强制计算
undefined
(前提是
T
不是
新类型

现在考虑代码(让我们假设它可以编译)

以及执行

bar undefined (\x::Int -> 4::Int)
这该怎么办?有人可能会说,它应该生成与
foo
相同的异常。如果是这样的话,参考透明度将意味着

let S = undefined :: S (Int->Int) in show (\x::Int -> 4::Int)
也会失败,但出现相同的异常。这意味着
let
正在计算
未定义的
表达式,与例如

let [] = undefined :: [Int] in 5
其计算结果为
5

实际上,
let
中的模式是惰性的:它们不强制表达式求值,这与
case
不同。这就是为什么

let (x,y) = undefined :: (Int,Char) in 5
成功计算为
5

如果在
e'
中需要一个
show
,人们可能想让
let S=e在e'
中评估
e
,但这感觉相当奇怪。同样,当计算
时,让S=e1;S=e2在show…
中不清楚是评估
e1
e2
,还是两者都评估


GHC目前选择用一条简单的规则来禁止所有这些情况:消除GADT时没有懒惰模式。

似乎就在附近。我认为
->
应该是
$
@bisserlis:不,是。@DanielWagner:我会的,但我不确定我自己是否理解它,我不愿意发布一个我无法解释的答案。相关答案:似乎就在附近。我认为
->
应该是
$
@bisserlis:不,是的。@DanielWagner:我愿意,但我不确定我自己是否理解它,我也不愿意发布一个我无法解释的答案。相关答案:最后一个例子(使用多个
let
s)更接近ghc源代码中给出的原因。简单的方法(从typechecker的角度)是将所有约束合并到一个上下文中。但在某些情况下,简化是无效的。因此,目前不允许使用这些情况。最后一个示例(使用多个
let
s)更接近ghc源代码中给出的原因。简单的方法(从typechecker的角度)是将所有约束合并到一个上下文中。但在某些情况下,简化是无效的。因此,目前不允许这些情况。