为什么Haskell缺少“明显的”类型类 [英] Why is Haskell missing "obvious" Typeclasses

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

问题描述

考虑面向对象的语言:

大多数来自面向对象编程背景的人都熟悉常见和直观各种语言的接口,捕捉Java的 收藏 & List 界面。 集合 是指不一定具有自然顺序/索引的对象集合。 List 是一个具有自然顺序/索引的集合。这些接口在Java中抽象了许多库数据结构,就像他们在其他语言中的等价接口一样,并且需要对这些接口有一个深入的了解才能与大多数库数据结构有效地工作。



转换到Haskell:

Haskell有一个类型类系统,类似于对象上的接口类型。 Haskell似乎有一个精心设计的类型层次结构,涉及到Functors,Applicative, Monads等类型的功能。他们显然需要正确且抽象良好的类型类。然而,当您查看许多Haskell的容器时( 列表 地图 Sequence Set 矢量 )它们几乎都具有非常相似的(或相同的)功能,但不是通过类型类抽象的。

一些示例:
$ b


  • null 用于测试空白$ b $元素计数 b
  • elem / 成员包含集合

  • 和/或 单行用于默认构建

  • union 为集合

  • (\\) / 差异设定差异

  • (!) / (!!)用于不安全索引(部分函数)
  • / 查找用于安全索引(总功能) b


如果我想使用上面的任何函数,但是我导入了两个或多个容器,我必须从导入的模块中隐藏函数,或者只显式导入来自模块的必要功能,或限定导入的模块。但是因为所有的功能都提供了相同的逻辑功能,所以它看起来很麻烦。如果函数是从类型类定义的,而不是在每个模块中分别定义的,编译器的类型推断机制就可以解决这个问题。只要它们共享类型类(即:让我们只使用 Sequence 而不是 List

为什么Haskell没有 Collection 和/或 可索引 type-class来统一&推广这些函数的一部分?

解决方案

部分原因是monads和arrow是Haskell的新创新功能,相对来说比较平凡。 Haskell作为一门研究语言有着悠久的历史,有趣的研究问题(设计monad实例和定义monads的通用操作)比工业强度抛光(定义容器API)获得更多的开发工作。 部分地,原因是这些类型来自三个不同的包(基础,容器和矢量),有三个独立的历史和设计师。这使得他们的设计师难以协调提供任何单一类型的实例。



部分原因是定义一个单一的类型类来覆盖所有五个类你提到的容器确实很难。 List,Sequence和Vector相对相似,但Map和Set具有完全不同的约束。对于列表,序列和矢量,您需要一个简单的构造函数类,但对于无法工作的Set,因为Set需要元素类型上的Ord实例。更糟糕的是,Map可以支持大多数方法,但是它的单例函数需要两个参数,其余的只需要一个。


Consider the Object-Oriented Languages:

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.

Transition to Haskell:

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.

Some Examples:

  • 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)

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).

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

解决方案

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.

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天全站免登陆