为什么这些不相等?
show $ if someCondition then someInt else some double
和
if someCondition then show someInt else show someDouble
[我了解,如果您将第一个示例中的if ... else
部分单独隔离为一个表达式,那么您就无法使用匿名求和类型(即Int | Double
的类型)来表示其类型,就像您可以轻松地在其中执行的操作一样TypeScript(提及TypeScript,因为它是我经常使用的语言,并且支持Sum类型),并且不得不诉诸使用Either
数据,然后基于该数据调用show
。
我在这里给出的示例很简单,但是对我来说,认为“好吧,我们将要显示某些东西,并且某些东西取决于someCondition
”,而不是“如果某些条件为true,则显示someInt,否则显示someDouble,这更有意义。 “,并且还可以减少代码重复(此处的显示重复了两次,但它也可能是一个长函数的应用程序,代替if ... else
可能要考虑> 2个分支)]
我认为编译器应该很容易地检查构成求和类型的每种类型(此处为Int | Double
)是否可用作show
函数的参数,并确定类型是否正确。 。更好的是,无论参数的类型如何,show
函数始终返回string
,因此编译器不必随身携带所有可能的“分支”(因此所有可能的类型)。
是否可以选择不存在这样的功能?还是我认为实施起来更难?
表达式的所有部分必须正确键入。 if someCondition then someInt else someDouble
的类型必须类似于exists a. Show a => a
,但是Haskell不支持这种存在性量化。
更新:作为chi points out in a comment,如果Haskell支持联合/交叉类型(与求和/乘积类型不同),也可以实现,但不幸的是,这不是可能的。
Haskell中的产品类型带有轻量级语法,用(,)
编写。一个具有轻量级语法的求和类型(例如(Int | String)
)将是一个好主意。现实更加复杂。让我们看看为什么(我对Num
享有一些自由,它们并不重要)。
if someCondition then 42 else "helloWorld"
如果这将返回类似(Int | String)
的类型的值,那么以下内容应返回什么?
if someCondition then 42 else 0
(Int | Int)
很明显,但是如果这与普通的Int
不同,那么我们将陷入严重麻烦。因此,(Int | Int)
应该与普通Int
相同。
可以立即看到,这不仅是求和类型的轻量级语法,而且是一种全新的语言功能。如果愿意,可以使用另一种类型的类型系统。我们应该有一个吗?
让我们看一下这个功能。
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,则知道在哪里可以找到它。