Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which polymorphism types are supported in Haskell?

Reading the Wikipedia definition of polymorphism, I come with a question:

Which polymorphism types are supported in Haskell and which are not?

Looks like Wikipedia do not contain a description for some polymorphism types like Levity Polymorphism which is new for me and supported in Haskell.

I wondering to have an extended list of Haskell Polymorphism followed with examples to explore deeply.

Looks like the main two are:

  • Parametric polymorphism
  • Ad-hoc polymorphism
like image 223
mkUltra Avatar asked May 27 '19 12:05

mkUltra


People also ask

What are polymorphic types in Haskell?

Parametric polymorphism In Haskell, this means any type in which a type variable, denoted by a name in a type beginning with a lowercase letter, appears without constraints (i.e. does not appear to the left of a =>). In Java and some similar languages, generics (roughly speaking) fill this role.

What are type classes in Haskell?

Type Classes are a language mechanism in Haskell designed to support general overloading in a principled way. They address each of the concerns raised above. They provide concise types to describe overloaded functions, so there is no expo- nential blow-up in the number of versions of an overloaded function.

What is the difference between ad hoc and universal polymorphism?

Universal or parametric polymorphism is another type of polymorphism. Unlike ad hoc, which is based on type, universal polymorphism is type-agnostic. Ad hoc polymorphism is derived from the loose translation of “ad hoc,” which is “for this.” That means the polymorphism relates specifically to certain data types.


1 Answers

There are at least four things that can count as polymorphism in current Haskell:

  • Parametric polymorphism. (Also kind polymorphism, polymorphism in the kinds instead of the types. Which I guess is parametric polymorphism one level above, so I'm not counting it as a separate entry.)
  • Ad-hoc polymorphism, the one enabled by typeclasses. Introduced in the How to make ad-hoc polymorphism less ad hoc paper.
  • Structural polymorphism. This is the one enabled by generics. A function can work over multiple data types that have different number of fields and constructors. For example, a generic equality function for records.
  • Levity polymorphism. Polymorphism over calling conventions / runtime representations of types. Described in the Levity Polymorphism paper.

There are two more types of polymorphism that might be introduced in future versions of Haskell:

  • Matchability polymorphism. Would allow higher-order type families to work with both type constructors and type families as arguments. Described in the paper Higher-order Type-level Programming in Haskell.

  • Multiplicity polymorphism. Would allow higher-order functions to work with both normal functions and linear functions as arguments. Described in the paper Linear Haskell Practical Linearity in a Higher-Order Polymorphic Language.

One might ask, why this whole panoply of polymorphisms? There seems to exist an overall design principle in Haskell that, whenever some challenge could be solved with either subtyping or polymorphism, polymorphism should be preferred.

For example, from the levity polymorphism paper:

We can now present the main idea of the paper: replace sub-kinding with kind polymorphism.

From the paper introducing matchability polymorphism:

At first you might think that we need subtyping, but instead we turn to polymorphism

From the linear Haskell paper:

The lack of subtyping is a deliberate choice in our design

Simon Peyton Jones himself makes the point at 47:00 in this talk.

Whenever you want to use subtyping, use polymorphism instead.

like image 95
danidiaz Avatar answered Sep 27 '22 23:09

danidiaz