求和类型-为什么Haskell中的'show(Int | Double)`不同于`(show Int)|(show Double)`
为什么这些不等同求和类型-为什么Haskell中的'show(Int | Double)`不同于`(show Int)|(show Double)`,haskell,compiler-construction,language-features,typechecking,Haskell,Compiler Construction,Language Features,Typechecking,为什么这些不等同 显示$if someCondition然后someInt其他一些double 及 如果是某个条件,则显示某个int,否则显示某个double 我理解如果你隔离如果。。。else在第一个示例中是表达式本身的一部分,那么您不能用匿名和类型来表示其类型,Int | Double,就像您可以在TypeScript中轻松完成的事情一样(提到TypeScript是因为它是我经常使用的语言,支持和类型),并且必须使用或数据,然后基于该数据调用show 我在这里给出的示例并不重要,但对我来
显示$if someCondition然后someInt其他一些double
及
如果是某个条件,则显示某个int,否则显示某个double
我理解如果你隔离如果。。。else
在第一个示例中是表达式本身的一部分,那么您不能用匿名和类型来表示其类型,Int | Double
,就像您可以在TypeScript中轻松完成的事情一样(提到TypeScript是因为它是我经常使用的语言,支持和类型),并且必须使用或数据,然后基于该数据调用show
我在这里给出的示例并不重要,但对我来说,更合理的想法是“好的,我们将展示一些东西,并且某些东西取决于someCondition
”,而不是“如果someCondition为真,那么展示someInt,否则展示someDouble”,并且允许更少的代码重复(此处显示重复两次,但也可能是一个长函数应用程序,而不是一个if…else
,可能需要考虑>2个分支)
在我看来,编译器应该很容易检查构成sum类型的每个类型(这里Int | Double
)可以用作show
函数的参数,并决定类型是否正确。更好的是show
函数总是返回一个字符串,而不管参数的类型如何,因此编译器不必携带所有可能的“分支”(因此所有可能的类型)
是选择了这样一个功能不存在?还是实现起来比我想的更难?表达式的所有部分都必须是类型良好的。的类型如果某个条件,那么另一个int someDouble
必须是类似于exists a的类型。Show a=>a
,但Haskell不支持这种存在量词反腐败
更新:同样,如果Haskell支持并集/交集类型(与总和/乘积类型不同),这也是可能的,但不幸的是,它不支持。在Haskell中,有使用轻量级语法编写的产品类型,如(,)
。有一种情况是,总和类型使用轻量级语法,如(Int | String)
,这将是一个好主意。现实更复杂。让我们看看原因(我对Num
有一些自由,它们并不重要)
如果这应该返回一个类似(Int | String)
类型的值,那么下面应该返回什么
if someCondition then 42 else 0
(Int | Int)
显然,但如果这与普通的Int
不同,那么我们就陷入了困境。因此(Int | Int)
应该与普通的Int
相同
你可以马上看到,这不仅仅是sum类型的轻量级语法,而是一个全新的语言特性。如果你愿意的话,可以使用另一种类型系统。我们应该有一个吗
让我们看看这个函数
mysteryType x a b = if x then a else b
现在,mysteryType
有什么类型?很明显
mysteryType :: Bool -> a -> b -> (a|b)
是吗?现在如果a
和b
是同一类型呢
let x = mysteryType True 42 0
这应该是简单的Int
,正如我们之前所同意的。现在mysteryType
有时返回匿名和类型,有时不返回,这取决于您传递的参数。您如何匹配这样一个表达式?您到底能用它做什么?除了“show”之类的琐碎事情之外(或者它将是其他类型类的任何方法的实例)不是很多。除非您向语言添加运行时类型信息,也就是说,typeof
是可用的,这使Haskell成为一种完全不同的语言
是的。为什么Haskell不是一个TypeScript?因为我们不需要另一个TypeScript。如果你想要TypeScript,你知道在哪里可以找到它。一个If…then…else…
,需要在then
和else
部分有相同的类型。在一些编程语言中,你可以将其视为三元运算符。我同意这个观点<在我的问题中,我不希望Haskell将Int
转换为Double
,反之亦然。我只是以这两种类型为例。你可以用a
替换所有Int
,在我的问题中用b
替换Double
,这两种类型都派生自Showde>。我知道Haskell中没有匿名和类型
,但我想知道为什么会是这种情况,以及是什么阻止我们设计语言来拥有它。我认为这样的类型被称为联合类型。和类型本质上是联合类型的一个标记变体,其中每个值都必须在t之外带有左/右标记内部类型的值。我希望使用联合类型的类型推断,以及Haskell的所有类型级功能,是很难实现的。如果x::Int | Bool
,并且我们必须编译show x
,在基于类型擦除的RTS中,没有简单的方法知道调用show
要使用哪个函数指针bably需要在运行时保留一些类型级别的信息。不使用匿名和类型是Haskell设计师的设计决策。我不太确定它们会带来什么样的好处,但我确实看到它们会使事情复杂化。所以我猜它们被忽略了,因为成本/效益比不存在。但绝对地说当然,你需要询问最初的语言设计者和/或当前的维护者。我认为这不是一个很好的问题,因为在设计一种语言的过程中有很多个人的观点和品味。(String,Int)
不是匿名的。它只是一种语法有趣的常规产品类型。(String | Int)
会有很大不同。从问自己开始
let x = mysteryType True 42 0