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

Meh*_*far 8 compiler-construction language-features haskell typechecking

为什么这些不相等?

show $ if someCondition then someInt else some double
Run Code Online (Sandbox Code Playgroud)

if someCondition then show someInt else show someDouble
Run Code Online (Sandbox Code Playgroud)

我了解,如果您将if ... else第一个示例中的部分本身与一个表达式隔离开,那么您就无法用匿名和类型来表示其类型Int | Double,就像您可以在TypeScript中轻松进行的操作(提及TypeScript,因为它是我经常使用的语言,该语言支持Sum类型),因此不得不诉诸于使用Either数据,然后基于调用show

我在这里给出的示例很简单,但对我来说,认为“好吧,我们将要显示某些东西,而某些东西取决于someCondition”,而不是“好吧,如果someCondition为true,则显示someInt,否则显示someDouble”,并且也允许减少代码重复(这里的显示重复了两次,但它也可能是一个长函数的应用程序,而不是if ... else可能要考虑的> 2个分支)

在我看来,对于编译器来说,检查构成求和类型的每种类型(在此处Int | Double)是否可以用作show函数的参数并确定类型是否正确应该很容易。更好的是,无论参数的类型如何,show函数始终会返回string,因此编译器不必随身携带所有可能的“分支”(因此所有可能的类型)。

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

Jos*_*ica 8

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

更新:正如chi在评论中指出的那样,如果Haskell支持联合/交叉类型(与求和/乘积类型不同),这也是可能的,但不幸的是,它不是。

  • 为了清楚起见,TypeScript在运行时提供了类型信息,因此它具有一个'typeof'运算符,该运算符可以弥补标记的不足并查看仍然使用哪种类型。Haskell已完全擦除了类型,因此,如果它支持此功能,那么将没有与之等效的功能。 (2认同)

n. *_* m. 6

There are product types with lightweight syntax, written (,), in Haskell. One would thing that a sum type with a lightweight syntax, something like (Int | String), would be a great idea. The reality is more complicated. Let's see why (I'm taking some liberties with Num, they are not important).

if someCondition then 42 else "helloWorld"
Run Code Online (Sandbox Code Playgroud)

If this should return a value of type like (Int | String), then what should the following return?

if someCondition then 42 else 0
Run Code Online (Sandbox Code Playgroud)

(Int | Int) obviously, but if this is distinct from plain Int then we're in deep trouble. So (Int | Int) should be identical to plain Int.

One can immediately see that this is not just lightweight syntax for sum types, but a wholly new language feature. A different kind of type system if you will. Should we have one?

Let's look at this function.

mysteryType x a b = if x then a else b
Run Code Online (Sandbox Code Playgroud)

Now what type does mysteryType have? Obviously

mysteryType :: Bool -> a -> b -> (a|b)
Run Code Online (Sandbox Code Playgroud)

right? Now what if a and b are the same type?

let x = mysteryType True 42 0
Run Code Online (Sandbox Code Playgroud)

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

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