Algebraic data type 2026-10-31
A type whose values are described by named data constructors with specified fields. For example,
data Tree a = One a | Two (Tree a) (Tree a) describes a leaf-labelled binary tree. Its two alternatives are distinguished by pattern matching; the recursive fields give a recursive type. Data type 2026-10-31
A classification of program values together with the operations permitted on them. An algebraic data type describes values by data constructors; a function type describes acceptable arguments and produced results.
Use pattern matching on the two data constructors, concatenating the left subtree's inorder traversal, the root label, and the right subtree's inorder traversal:Here
data Tree = Leaf | Fork Tree Int Tree
inorder :: Tree -> [Int]
inorder Leaf = []
inorder (Fork l x r) = inorder l ++ [x] ++ inorder rLeaf represents the empty binary tree, rather than a labelled leaf. The printed declaration uses type; an executable Haskell algebraic data type requires data, as above. By structural induction, the two equations return precisely the prescribed inorder traversal:Tree is a type constructor, taking the element type parameter a to the algebraic data type Tree a. It is not a value and has no ordinary value-level function type; its kind of a type is * -> *. The other names are data constructors with polymorphic type signatures:One :: a -> Tree a
Two :: Tree a -> Tree a -> Tree aOne constructs a leaf-labelled binary tree with one leaf; Two joins two such trees under a new internal node. Unlike a general binary tree representation with empty child slots, this representation has no empty tree.[ref]Count each data constructor once, including each
Two:size :: Tree a -> Int
size (One _) = 1
size (Two l r) = 1 + size l + size rStructural induction verifies the count: a leaf contributes one; an internal node contributes itself and the disjoint occurrences in its two subtrees. Fully evaluating the result takes linear time in the number of nodes. This type signature uses machine
Int as usual in the examination; Integer avoids overflow for arbitrarily large inputs.The natural tree fold replaces each data constructor by the supplied operation:
fold :: (a -> b) -> (b -> b -> b) -> Tree a -> b
fold one two (One x) = one x
fold one two (Two l r) = two (fold one two l) (fold one two r)Its reconstruction identity is
fold One Two = id. More generally a function h equals fold one two on finite trees exactly when h (One x) = one x and h (Two l r) = two (h l) (h r). These equations determine the result by structural induction, expressing why this is the natural structural recursion for this datatype.Replace the leaf data constructor by the constant one and the internal data constructor by addition with one extra node:
size :: Tree a -> Int
size = fold (const 1) (\m n -> 1 + m + n)One simple right-associated representation is
rep :: [a] -> CatList a
rep [] = Nil
rep (x:xs) = Cat (One x) (rep xs)It constructs two data constructors per input element and one final
Nil, so full construction takes time and produces constructors. Structural induction shows that its denotation is the original list.Use a type synonym for names and an algebraic data type with the two teams and their goals in the given positional order:
type Team = String
data Match = Match Team Int Team IntTeam is a synonym, not a new runtime wrapper. Match on the left is the type constructor, while the same spelling on the right is a data constructor in a different namespace. Its value-level type signature is Match :: Team -> Int -> Team -> Int -> Match. Tree fold Created 2026-10-24 Updated 2026-10-31
A structural recursion replacing the empty binary tree by a value and a nonempty node by a combining function on its two folded children and root label. The result type may itself be a function type, allowing a fold to construct a membership predicate or a difference list rather than traversing all branches for every subsequent query.
More generally, choose one operation for each data constructor. For a leaf-labelled binary tree represented by
One a | Two (Tree a) (Tree a), the tree fold instead has type signature (a -> b) -> (b -> b -> b) -> Tree a -> b: one operation handles the leaf label, and the other combines the two folded children. Replacing the operations by the original data constructors reconstructs the input, as structural induction proves. Type constructor 2026-10-31
A type-level constructor accepting the number and kinds of type arguments specified by its kind of a type. For example,
Tree accepts one ordinary type and produces Tree a; it has kind * -> *. A data constructor such as One operates at the value level instead. The two levels can use separate namespaces in a programming language.