The abstract list type
L with elements of some type
E (a
monomorphic list) is defined by the following functions: :nil: () →
L :cons:
E ×
L →
L :first:
L →
E :rest:
L →
L with the axioms :first (cons (
e,
l)) =
e :rest (cons (
e,
l)) =
l for any element
e and any list
l. It is implicit that :cons (
e,
l) ≠
l :cons (
e,
l) ≠
e :cons (
e1,
l1) = cons (
e2,
l2) if
e1 =
e2 and
l1 =
l2 Note that first (nil ()) and rest (nil ()) are not defined. These axioms are equivalent to those of the abstract
stack data type. In
type theory, the above definition is more simply regarded as an
inductive type defined in terms of constructors:
nil and
cons. In algebraic terms, this can be represented as the transformation 1 +
E ×
L →
L.
first and
rest are then obtained by
pattern matching on the
cons constructor and separately handling the
nil case.
The list monad The list type forms a
monad with the following functions (using
E* rather than
L to represent monomorphic lists with elements of type
E): :\text{return}\colon A \to A^{*} = a \mapsto \text{cons} \, a \, \text{nil} :\text{bind}\colon A^{*} \to (A \to B^{*}) \to B^{*} = l \mapsto f \mapsto \begin{cases} \text{nil} & \text{if} \ l = \text{nil}\\ \text{append} \, (f \, a) \, (\text{bind} \, l' \, f) & \text{if} \ l = \text{cons} \, a \, l' \end{cases} where
append is defined as: :\text{append}\colon A^{*} \to A^{*} \to A^{*} = l_1 \mapsto l_2 \mapsto \begin{cases} l_2 & \text{if} \ l_1 = \text{nil} \\ \text{cons} \, a \, (\text{append} \, l_1' \, l_2) & \text{if} \ l_1 = \text{cons} \, a \, l_1' \end{cases} Alternatively, the monad may be defined in terms of operations
return,
fmap and
join, with: :\text{fmap} \colon (A \to B) \to (A^{*} \to B^{*}) = f \mapsto l \mapsto \begin{cases} \text{nil} & \text{if} \ l = \text{nil}\\ \text{cons} \, (f \, a) (\text{fmap} f \, l') & \text{if} \ l = \text{cons} \, a \, l' \end{cases} :\text{join} \colon {A^{*}}^{*} \to A^{*} = l \mapsto \begin{cases} \text{nil} & \text{if} \ l = \text{nil}\\ \text{append} \, a \, (\text{join} \, l') & \text{if} \ l = \text{cons} \, a \, l' \end{cases} Note that
fmap,
join,
append and
bind are well-defined, since they're applied to progressively deeper arguments at each recursive call. The list type is an additive monad, with
nil as the monadic zero and
append as monadic sum. Lists form a
monoid under the
append operation. The identity element of the monoid is the empty list,
nil. In fact, this is the
free monoid over the set of list elements. ==See also==