为什么 haskell 没有异构列表
我不明白为什么我无法在 haskell 中构造一个类似于 [1,"1",1.1]
的列表。我不认为静态类型会妨碍我,因为我认为 head
现在会有一个定义错误的类型,但后来我想了想,运行时系统没有理由不这么做。每当将列表输入其中时,t 都会实例化不同版本的 head
,因此 head [1,"1",1.1]
将被键入为 List->; Int
和 head (tail [1,"1",1.1])
将被键入为 List->String
。既然运行时已经做了很多簿记工作,为什么它不提供各种前奏函数的更高级的多态(或者通用)版本呢?我在这里缺少什么?
I don't understand why I can't construct a list that looks like [1,"1",1.1]
in haskell. I don't think it's static typing that gets in the way because I thought that head
would now have an ill defined type but then I thought about it and there is no reason the run-time system doesn't instantiate a different version of head
whenever a list is fed into it so head [1,"1",1.1]
would be typed as List->Int
and head (tail [1,"1",1.1])
would be typed as List->String
. Since the run-time already does a lot of bookkeeping why doesn't it provide fancier polymorphic (or is it generic) versions of the various prelude functions? What am I missing here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
确实是打字阻止了这种情况。考虑列表的定义(注意类型参数
a
,它在您的类型中缺失):在
Cons a (List a)
中,您可以看到列表头部的元素必须与其后面的元素具有相同的类型。为了回答你的问题,你并没有错过很多:正如你所说,运行时可以做到这一点,但在 Haskell 中,你希望在编译时而不是运行时做出这些类型决定。如果您想要异构列表,您可以在 Oleg Kiselyov 的作品中看到一些魔法 HList(= 异构列表)。它可能不完全是您想要的,但大致方向相同。
It is indeed the typing that prevents this. Consider the definition of a list (notice the type parameter
a
, which is missing from your types):In the
Cons a (List a)
you can see that the type of thing at the head of the list must be the same type as the elements that follow it. To answer your question, you're not missing a lot: as you say the runtime could do it, but in Haskell you want to make these typing decisions at compile-time, not runtime.If you want heterogeneous lists, you can see some wizardry by Oleg Kiselyov in his work on HList (= Heterogeneous List). It may not be exactly what you want, but it's in the same rough direction.
因为在 Haskell 中,所有类型在编译时都是已知的。不存在需要等到运行时才能查看类型的情况。因为这足以完成您在动态类型系统中想做的任何事情,同时更容易推理启动。
Because in Haskell all types are known at compile-time. There's no such thing as waiting until runtime to see what the type will be. And because this is sufficient to do anything you could want to do in a dynamically-typed system, while being easier to reason about to boot.
正如您所知,实际上有一个用于异构列表的包,使用了不平凡的技术,您确实应该确保在深入研究之前很好地理解类型系统。由于类型系统的原因,默认情况下你没有这个。 Haskell 中的列表不仅仅是一个列表。它是a 的列表,'a' 可以是Int、String,无论你想要什么。但是,一个列表只能包含一种类型的值。
请注意,您可以使用存在量化来定义满足某些约束的元素的“异构列表”,但我认为您还没有做到这一点,并且在进一步讨论之前确实应该专注于理解此处的其他答案。
Just so you know, there actually is a package for heterogeneous lists, using non-trivial techniques and you really should make sure you understand the type system well before diving into this. You don't have this by default because of the type system. A list in Haskell isn't just a list. It's a list of a's, 'a' being Int, String, whatever you want. BUT, one list can contain only one type of values.
Note that you can define "heterogeneous lists" of elements satisfying some constraints using existential quantification, but I think you're not there yet and really should focus on understanding the other answers here before going any further.
有一种称为 HList 的异构列表类型(可在 Hackage 上找到),但请注意,列表的内容可能有一种类型。考虑这样的事情:
您的数据有一种难以出现的类型,例如:
在许多情况下,您的数据有一种您只需要寻找的类型。
There is a heteregenous list type called HList (available on Hackage), but note that there probably is a type for the contents of your list. Consider something like this:
Your data has a type struggling to emerge, e.g.:
In many cases, your data has a type that you just need to seek out.
查看异构集合
Look at Heterogenous collections