求和类型-为什么在Haskell中show(Int | Double)与`(show Int)|不同? (显示Double)`

问题描述 投票:1回答:2

为什么这些不相等?

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,因此编译器不必随身携带所有可能的“分支”(因此所有可能的类型)。

是否可以选择不存在这样的功能?还是我认为实施起来更难?

haskell compiler-construction language-features typechecking
2个回答
3
投票

表达式的所有部分必须正确键入。 if someCondition then someInt else someDouble的类型必须类似于exists a. Show a => a,但是Haskell不支持这种存在性量化。

更新:作为chi points out in a comment,如果Haskell支持联合/交叉类型(与求和/乘积类型不同),也可以实现,但不幸的是,这不是可能的。


1
投票

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)

对吗?现在,如果ab是同一类型怎么办?

let x = mysteryType True 42 0

如我们先前所同意的,这应该是简单的Int。现在,mysteryType有时会返回匿名求和类型,有时则不会,这取决于您传递的参数。您如何模式匹配这样的表达式?你到底能做什么?除了琐碎的事情,例如“ show”(或其他类型类的任何方法,它将是其实例),不是很多。除非您向该语言添加运行时类型信息,否则,typeof可用-这使Haskell成为全部不同的语言。

是的。为什么Haskell没有TypeScript?因为我们不需要另一个TypeScript。如果需要TypeScript,则知道在哪里可以找到它。

© www.soinside.com 2019 - 2024. All rights reserved.