为什么 Haskell 缺少“显而易见的"?类型类 [英] Why is Haskell missing "obvious" Typeclasses

查看:22
本文介绍了为什么 Haskell 缺少“显而易见的"?类型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑面向对象的语言:

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

Most people coming from an object-oriented programming background, are familiar with the common and intuitive interfaces in various languages that capture the essence of Java's Collection & List interfaces. Collection refers to a collection of objects which doesn't necessarily have an natural ordering/indexing. A List is a collection which has a natural ordering/indexing. These interfaces abstract many library data-structures in Java, as do their equivalent interfaces in other languages, and an intimate understanding of these interfaces are required to work effectively with most library data-structures.

过渡到 Haskell:

Haskell 有一个类型类系统,它作用于类型类似于对象上的接口.Haskell 似乎对函子、Applicative、当类型考虑功能时,Monads 等.他们显然想要正确且抽象的类型类.然而,当您查看许多 Haskell 的容器时(List,地图,序列Set,Vector) 它们几乎都具有非常相似(或相同)的功能,但没有通过类型类进行抽象.

Haskell has a type-class system which acts on types analogously to interfaces on objects. Haskell seems to have a well designed type-class hierarchy with regard to Functors, Applicative, Monads, etc. when the type regard functionality. They obviously want correct and well-abstracted type-classes. Yet when you look at many Haskell's containers (List,Map,Sequence,Set,Vector) they almost all have very similar (or identical) functions, yet aren't abstracted through type-classes.

一些例子:

  • null 用于测试空性"
  • length/size 元素数量
  • elem/member 用于集合包含
  • empty and/or singleton 用于默认构造
  • union 用于设置联合
  • (\)/diff 用于集差
  • (!)/(!!) 用于不安全的索引(部分功能)
  • (!?)/lookup 用于安全索引(总功能)
  • null for testing "emptyness"
  • length/size for element count
  • elem/member for set inclusion
  • empty and/or singleton for default construction
  • union for set union
  • (\)/diff for set difference
  • (!)/(!!) for unsafe indexing (partial function)
  • (!?)/lookup for safe indexing (total function)

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

If I want to use any of the functions above, but I have imported two or more containers I have to start hiding functions from the imported modules, or explicitly import only the necessary functions from the modules, or qualifying the imported modules. But since all the functions provide the same logical functionality, it just seems like a hassle. If the functions were defined from type-classes, and not separately in each module, the compiler's type inference mechanics could resolve this. It would also make switching underlying containers simple as long as they shared the type-classes (ie: lets just use a Sequence instead of List for better random access efficiency).

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

Why doesn't Haskell have a Collection and/or Indexable type-class(es) to unify & generalize some of these functions?

推荐答案

部分原因是 monads 和箭头是 Haskell 的新的、创新的特性,而集合相对更普通.Haskell 作为一种研究语言有着悠久的历史.有趣的研究问题(设计 monad 实例和定义 monad 的通用操作)比工业强度"抛光(定义容器 API)需要更多的开发工作.

Partly, the reason is that monads and arrows are new, innovative features of Haskell, while collections are relatively more mundane. Haskell has a long history as a research language; interesting research questions (designing monad instances & defining generic operations for monads) get more development effort than "industrial-strength" polishing (defining container APIs).

部分原因是这些类型来自三个不同的包(基础、容器和矢量),具有三个不同的历史和设计者.这使得他们的设计者更难协调提供任何单一类型类的实例.

Partly, the reason is that those types come from three different packages (base, containers, and vector), with three separate histories and designers. That makes it harder for their designers to coordinate on providing instances of any single type class.

部分原因是定义一个类型类来覆盖您提到的所有五个容器真的很难.List、Sequence、Vector比较相似,但Map和Set的约束完全不同.对于 List、Sequence 和 Vector,您需要一个简单的构造函数类,但对于 Set 则行不通,因为 Set 需要元素类型上的 Ord 实例.更糟糕的是,Map 可以支持你的大部分方法,但它的单例函数需要两个参数,其余的只需要一个.

Partly, the reason is that defining a single type class to cover all five of the containers you mentioned is really hard. List, Sequence, and Vector are relatively similar, but Map and Set have completely different constraints. For List, Sequence, and Vector, you want a simple constructor class, but for Set that won't work, since Set requires an Ord instance on the element type. Even worse, Map can support most of your methods, but its singleton function needs two parameters where the rest need only one.

这篇关于为什么 Haskell 缺少“显而易见的"?类型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆