# GetWiki

*algebraic data type*

ARTICLE SUBJECTS

being →

database →

ethics →

fiction →

history →

internet →

language →

linux →

logic →

method →

news →

policy →

purpose →

religion →

science →

software →

truth →

unix →

wiki →

ARTICLE TYPES

essay →

feed →

help →

system →

wiki →

ARTICLE ORIGINS

critical →

forked →

imported →

original →

algebraic data type

[ temporary import ]

**please note:**

- the content below is remote from Wikipedia

- it has been imported raw for GetWiki

**algebraic data type**is a kind of composite type, i.e., a type formed by combining other types.Two common classes of algebraic types are product types (i.e., tuples and records) and sum types (i.e., tagged or disjoint unions or

*variant types*).Records and variants - OCaml manual section 1.4{{dead link|date=October 2015}}The values of a product type typically contain several values, called

*fields*. All values of that type have the same combination of field types. The set of all possible values of a product type is the set-theoretic product, i.e., the Cartesian product, of the sets of all possible values of its field types.The values of a sum type are typically grouped into several classes, called

*variants*. A value of a variant type is usually created with a quasi-functional entity called a

*constructor*. Each variant has its own constructor, which takes a specified number of arguments with specified types. The set of all possible values of a sum type is the set-theoretic sum, i.e., the disjoint union, of the sets of all possible values of its variants. Enumerated types are a special case of sum types in which the constructors take no arguments, as exactly one value is defined for each constructor.Values of algebraic types are analyzed with pattern matching, which identifies a value by its constructor or field names and extracts the data it contains.Algebraic data types were introduced in Hope, a small functional programming language developed in the 1970s at the University of Edinburgh.CONFERENCE, Presentations included Rod Burstall, Dave MacQueen, and Don Sannella on Hope, the language that introduced algebraic data types, A history of Haskell: being lazy with class,weblink Paul Hudak, John Hughes, Simon Peyton Jones, Philip Wadler, Proceedings of the third ACM SIGPLAN conference on History of programming languages,

## Examples

One of the most common examples of an algebraic data type is the singly linked list. A list type is a sum type with two variants, Nil for an empty list and Cons*x*

*xs*for the combination of a new element

*x*with a list

*xs*to create a new list. Here is an example of how a singly linked list would be declared in Haskell:data List a = Nil | Cons a (List a)Cons is an abbreviation of

*cons*truct. Many languages have special syntax for lists defined in this way. For example, Haskell and ML use [] for Nil, : or :: for Cons, respectively, and square brackets for entire lists. So Cons 1 (Cons 2 (Cons 3 Nil)) would normally be written as 1:2:3:[] or [1,2,3] in Haskell, or as 1::2::3::[] or [1;2;3] in ML.For a slightly more complex example, binary trees may be implemented in Haskell as follows:data Tree = Empty

| Leaf Int

| Node Tree Tree

Here, Empty represents an empty tree, Leaf contains a piece of data, and Node organizes the data into branches.In most languages that support algebraic data types, it is possible to define parametric types. Examples are given later in this article.Somewhat similar to a function, a data constructor is applied to arguments of an appropriate type, yielding an instance of the data type to which the type constructor belongs. For example, the data constructor Leaf is logically a function Int -> Tree, meaning that giving an integer as an argument to Leaf produces a value of the type Tree. As Node takes two arguments of the type Tree itself, the datatype is recursive.Operations on algebraic data types can be defined by using pattern matching to retrieve the arguments. For example, consider a function to find the depth of a Tree, given here in Haskell:
| Node Tree Tree

depth :: Tree -> Int

depth Empty = 0

depth (Leaf n) = 1

depth (Node l r) = 1 + max (depth l) (depth r)

Thus, a Tree given to depth can be constructed using any of Empty, Leaf, or Node and must be matched for any of them respectively to deal with all cases. In case of Node, the pattern extracts the subtrees l and r for further processing.Algebraic data types are highly suited to implementing abstract syntax. For example, the following algebraic data type describes a simple language representing numerical expressions:data Expression = Number Int
depth Empty = 0

depth (Leaf n) = 1

depth (Node l r) = 1 + max (depth l) (depth r)

| Add Expression Expression

| Minus Expression Expression

| Mult Expression Expression

| Divide Expression Expression

An element of such a data type would have a form such as Mult (Add (Number 4) (Minus (Number 0) (Number 1))) (Number 2).Writing an evaluation function for this language is a simple exercise; however, more complex transformations also become feasible. For example, an optimization pass in a compiler might be written as a function taking an abstract expression as input and returning an optimized form.| Minus Expression Expression

| Mult Expression Expression

| Divide Expression Expression

## Explanation

What is happening is that there is a datatype which can be*one of several types of things*. Each

*type of thing*is associated with an identifier called a

*constructor*, which can be viewed as a kind of tag for that kind of data. Each constructor can carry with it a different type of data. A constructor could carry no data (e.g., "Empty" in the example above), or one piece of data (e.g., â€œLeafâ€ has one Int value), or multiple pieces of data (e.g., â€œNodeâ€ has two Tree values).To do something with a value of this Tree algebraic data type, it is

*deconstructed*using a process termed

*pattern matching*. It involves

*matching*the data with a series of

*patterns*. The example function "depth" above pattern-matches its argument with three patterns. When the function is called, it finds the first pattern that matches its argument, performs any variable bindings that are found in the pattern, and evaluates the expression corresponding to the pattern.Each pattern above has a form that resembles the structure of some possible value of this datatype. The first pattern simply matches values of the constructor

*Empty*. The second pattern matches values of the constructor

*Leaf*. Patterns are recursive, so then the data that is associated with that constructor is matched with the pattern "n". In this case, a lowercase identifier represents a pattern that matches any value, which then is bound to a variable of that name â€” in this case, a variable â€œnâ€ is bound to the integer value stored in the data type â€” to be used in the expression to evaluate.The recursion in patterns in this example are trivial, but a possible more complex recursive pattern would be something like Node (Node (Leaf 4) x) (Node y (Node Empty z)). Recursive patterns several layers deep are used for example in balancing red-black trees, which involve cases that require looking at colors several layers deep.The example above is operationally equivalent to the following pseudocode:

switch on (data.constructor)

case Empty:

return 0

case Leaf:

let n = data.field1

return 1

case Node:

let l = data.field1

let r = data.field2

return 1 + max (depth l) (depth r)

The comparison of this with pattern matching will point out some of the advantages of algebraic data types and pattern matching. The first advantage is type safety. The pseudocode above relies on the diligence of the programmer to not access field2 when the constructor is a Leaf, for example. Also, the type of field1 is different for Leaf and Node (for Leaf it is Int; for Node it is Tree), so the type system would have difficulties assigning a static type to it in a safe way in a traditional record data structure. However, in pattern matching, the type of each extracted value is checked based on the types declared by the relevant constructor, and how many values can be extracted is known based on the constructor, so it does not face these problems.Second, in pattern matching, the compiler statically checks that all cases are handled. If one of the cases of the case Empty:

return 0

case Leaf:

let n = data.field1

return 1

case Node:

let l = data.field1

let r = data.field2

return 1 + max (depth l) (depth r)

*depth*function above were missing, the compiler would issue a warning, indicating that a case is not handled. This task may seem easy for the simple patterns above, but with many complex recursive patterns, the task becomes difficult for the average human (or compiler, if it must check arbitrary nested if-else constructs) to handle. Similarly, there may be patterns which never match (i.e., are already covered by prior patterns), and the compiler can also check and issue warnings for these, as they may indicate an error in reasoning.Do not confuse these patterns with regular expression patterns used in string pattern matching. The purpose is similar: to check whether a piece of data matches certain constraints, and if so, extract relevant parts of it for processing. However, the mechanism is very different. This kind of pattern matching on algebraic data types matches on the structural properties of an object rather than on the character sequence of strings.

## Theory

A general algebraic data type is a possibly recursive sum type of product types. Each constructor tags a product type to separate it from others, or if there is only one constructor, the data type is a product type. Further, the parameter types of a constructor are the factors of the product type. A parameterless constructor corresponds to the empty product. If a datatype is recursive, the entire sum of products is wrapped in a recursive type, and each constructor also rolls the datatype into the recursive type.For example, the Haskell datatype:
data List a = Nil | Cons a (List a)

is represented in type theory aslambda alpha. mu beta. 1 + alpha times betawith constructors mathrm{nil}_alpha = mathrm{roll} (mathrm{inl} langlerangle) and mathrm{cons}_alpha x l = mathrm{roll} (mathrm{inr} langle x, lrangle).The Haskell List datatype can also be represented in type theory in a slightly different form, thus:mu phi. lambda alpha. 1 + alpha times phi alpha.(Note how the mu and lambda constructs are reversed relative to the original.) The original formation specified a type function which body was a recursive type. The revised version specifies a recursive function on types. (The type variable phi is used to suggest a function rather than a *base type*like beta, since phi is like a Greek

*f*.) The function must also now be applied phi to its argument type alpha in the body of the type.For the purposes of the List example, these two formulations are not significantly different; but the second form allows expressing so-called nested data types, i.e., those where the recursive type differs parametrically from the original. (For more information on nested data types, see the works of Richard Bird, Lambert Meertens, and Ross Paterson.)In set theory the equivalent of a sum type is a disjoint union, a set which elements are pairs consisting of a tag (equivalent to a constructor) and an object of a type corresponding to the tag (equivalent to the constructor arguments).

## Programming languages with algebraic data types

Many programming languages incorporate algebraic data types as a first class notion, including:{{Columns-list|colwidth=30em|- Ceylon
- Clean
- CoqCalculus of Inductive Constructions, and basic standard libraries : Datatypes and Logic.
- C++WEB,weblink CppCon 2016: Ben Deane â€œUsing Types Effectively",
- Elm
- F
- F
- Haskell
- Haxe]weblink
- Hope
- Idris
- KotlinWEB,weblink Classes and Inheritance - Kotlin Programming Language,
- Limbo
- Language Of Temporal Ordering Specification (LOTOS)
- Mercury
- Miranda
- Nemerle
- Nim
- OCaml
- Opa
- OpenCog
- PonyWEB,weblink Pony,
- Racket
- ReasonWEB,weblink Reason,
- Rust
- Scala
- Standard ML
- Swift
- Tom
- TypeScript
- Visual Prolog

## See also

- Disjoint union
- Generalized algebraic data type
- Initial algebra
- Quotient type
- Tagged union
- Type theory
- Visitor pattern

## References

{{Reflist}}{{FOLDOC|algebraic+data+type|algebraic data type}}{{Data types}}**- content above as imported from Wikipedia**

- "

- time: 5:00am EDT - Mon, Apr 22 2019

- "

__algebraic data type__" does not exist on GetWiki (yet)- time: 5:00am EDT - Mon, Apr 22 2019

[ this remote article is provided by Wikipedia ]

LATEST EDITS [ see all ]

GETWIKI 09 MAY 2016

GETWIKI 18 OCT 2015

GETWIKI 20 AUG 2014

GETWIKI 19 AUG 2014

GETWIKI 18 AUG 2014

© 2019 M.R.M. PARROTT | ALL RIGHTS RESERVED