haskell - 为什么 Haskell 缺少 "obvious"类型类

标签 haskell typeclass abstraction standard-library

考虑面向对象的语言:

大多数人都有面向对象编程背景,熟悉各种语言中常见且直观的界面,这些界面捕获了 Java 的精髓 Collection & List接口(interface)。 集合是指不一定具有自然排序/索引的对象集合。 List 是一个具有自然排序/索引的集合。这些接口(interface)抽象了 Java 中的许多库数据结构,其他语言中的等效接口(interface)也是如此,并且需要对这些接口(interface)有深入的了解才能有效地处理大多数库数据结构。

过渡到 Haskell:

Haskell 有一个类型类系统,它作用于类型,类似于对象上的接口(interface)。 Haskell 似乎有一个 well designed type-class hierarchy当类型考虑功能时,涉及 Functor、Applicative、Monad 等。他们显然想要correct and well-abstracted type-classes 。然而,当你查看许多 Haskell 的容器( ListMapSequenceSetVector )时,它们几乎都具有非常相似(或相同)的功能,但不是通过类型类抽象的.

一些示例:

  • null 用于测试“空”
  • 长度/元素计数的大小
  • elem/member 用于集合包含
  • 和/或 singleton 用于默认构造
  • union 用于集合并集
  • (\\)/diff 用于设置差异
  • (!)/(!!) 用于不安全索引(部分函数)
  • (!?)/查找以进行安全索引(总功能)

如果我想使用上述任何函数,但我导入了两个或更多容器,我必须开始隐藏导入模块中的函数,或者仅从模块中显式导入必要的函数,或者限定导入的模块。但由于所有函数都提供相同的逻辑功能,因此看起来很麻烦。如果函数是从类型类定义的,而不是在每个模块中单独定义的,则编译器的类型推断机制可以解决此问题。只要底层容器共享类型类,它也会使切换底层容器变得简单(即:让我们只使用 Sequence 而不是 List 以获得更好的随机访问效率)。

为什么 Haskell 没有一个 Collection 和/或 Indexable 类型类来统一并概括其中一些功能?

最佳答案

正如其他答案所指出的,Haskell 倾向于使用不同的词汇。但是,我认为他们没有很好地解释差异的原因

在像 Java 这样的语言中,函数不是“一等公民”;而是“一等公民”。确实,最新版本中提供了匿名函数,但这种风格的界面(Collection、Indexable、Interable 等)是在此之前设计的。

这使得传递我们的代码变得乏味,因此我们更喜欢将其他人的数据传递给我们的代码。例如:

  • 实现 Java 的 Iterable 的数据让我们编写 for (Foo x : anIterable) { ... }
  • 实现 PHP ArrayAccess 的数据让我们可以编写 anArrayAccess[anIndex]

这种风格也可以在实现生成器的面向对象语言中看到,因为这是我们在 aGenerator 中编写 for yieldedElement: ... 的另一种方式。

Haskell 对类型类采取了不同的方法:我们更喜欢将我们的代码传递给其他人的数据。一些(简化的)示例:

  • 仿函数接受我们的代码并将其应用到它们“包含”的任何元素
  • Monad接受我们的代码并以某种“序列”应用它
  • Foldable接受我们的代码并使用它来“减少”其内容

Java 只需要 Iterable,因为我们必须在我们的 for 循环中调用我们的代码,因此我们可以确保它被正确调用。 Haskell 需要更具体的类型类,因为其他人的代码将调用我们的代码,因此我们需要指定如何调用它;它是 map 折叠展开等吗?

值得庆幸的是,类型系统帮助我们选择正确的方法;)

关于haskell - 为什么 Haskell 缺少 "obvious"类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25191659/

相关文章:

Haskell 中的正则表达式和字符串库

haskell - `pure x = (\_ -> x)` 是什么意思?

audio - 如何提取音频数据以进行比较?

python - 不使用lambda的python中的抽象函数

c# - 将对象属性与规则匹配的算法

haskell - 在未装箱的向量上内存函数会导致其挂起

haskell - 上次更新后,docksEventHook 的 Xmonad 警告和错误

Scala - 应用于隐式参数选择的 Co/Contra-Variance

scala - 嵌套案例类之间的递归转换,其中目标中的字段是源类的未对齐子集

java - 用抽象来创建类也是封装吗?