
Algebraic Data Types - ALee
http://tech.esper.com/2014/07/30/algebraic-data-types/
======
nice_uname_nerd
If you haven't seen any category theory, you might be interested to know that
the diagrams the author draws are valuable and important in modern pure math
as well. Those last two diagrams totally capture the idea of what a product or
variant (coproduct, in math terminology) is.

In general, there are a lot of algebraic structures whose essence is captured
by some diagramatic property like these, such as tensor products or fiber
products. They're called universal properties. Unfortunately the wikipedia
page looks pretty poorly written, but you might find it interesting
nonetheless.

[http://en.wikipedia.org/wiki/Universal_property](http://en.wikipedia.org/wiki/Universal_property)

------
jallmann
Nice article, I never considered the duality of product and sum types before.

The importance of effective ADT usage is generally under-emphasized when
discussing the benefits of statically typed FP languages* like OCaml and
Haskell — even though it is _the_ way to maximize the utility of such
languages, IMO.

With the right data representation, composability improves and algorithms fall
into place naturally. This is further enhanced by a language like OCaml —
since the compiler catches type errors and non-exhaustive matches on ADTs, any
bugs are likely holes in your application model.

There are many benefits in using ADTs, modules and other type-system features
to guide your program design. Others have described those benefits very well
already — just read anything by Yaron Minsky or Jane Street.

* Data modeling is critical for any problem domain, and statically typed, non-FP languages (Java, C++, etc) certainly have facilities to encourage effective modelling, but languages in the vein of OCaml and Haskell really push to make the type system do as much work as possible.

~~~
tel
I wrote a post emphasizing the duality of products and sums. It's a really
deep subject!

[http://tel.github.io/2014/07/23/types_of_data/](http://tel.github.io/2014/07/23/types_of_data/)

~~~
bjeanes
I loved reading this the other day. Thanks again for writing it. I'll be
coming to this post often, I think.

~~~
tel
I'm glad you enjoyed it! I'm working on one or two most posts in this vein in
order to introduce quantified types and recursive types. So: more to come!

------
austinz
Enjoyed this article. Another good read on ADTs:
[http://tel.github.io/2014/07/23/types_of_data/](http://tel.github.io/2014/07/23/types_of_data/),
and for a Swift-specific take:
[http://tel.github.io/2014/07/26/types_of_data_in_swift/](http://tel.github.io/2014/07/26/types_of_data_in_swift/)

~~~
devty
thank you for the link!

------
kawa
BTW: Union types ("tagged unions") predate OOP by some years and thus were
there long before OCaml or Haskell. Algol68 had them and also Pascal for
example. The invention of ML was pattern matching on those data structures.

~~~
ericssmith
FWIW, Peter Landin sowed the seeds in "Mechanical Evaluation of Expressions"
in 1964 in his description of recursive discriminated union for lists:

A list is either null or else has a head (h) and a tail (t) which is a list.

Rod Burstall picked up on this in "Proving Properties of Progams by Structural
Induction" (1968) in an extension to Landin's ISWIM that used pattern matching
on these. If you look closely the pattern matching was present in his if-then-
else syntax, but he changed it to the more convenient "case".

------
rrradical
I wrote recently about the option type specifically (called Maybe in Haskell):
[http://asivitz.com/posts/learn_to_love_maybe_kick_null](http://asivitz.com/posts/learn_to_love_maybe_kick_null)

Swift has it, but it lets you easily subvert its meaning ('trust me, it's not
null'), so I don't think it's as useful as it is in the usual functional
languages.

------
mathgenius
I can never get enough of the arrow theory.

Here is a malformed question that occurs to me just now:

In a language like python i can form instances of a product type using tuples,
but making instances of a sum (variant) type ... ?

How is it that the duality is broken when I no longer have variable
declarations? Or is every object instance already a variant (of every possible
subclass) ?

~~~
noelwelsh
In a language like Python you can consider there to be one type called, say,
ThePythonType, or which all types are a variant. Then all objects have type
ThePythonType.

A more useful type system would have "union types". They differ from sum types
in that you can construct a union type from existing types in an ad-hoc
manner. For example, if you have a function that returns a string or nil you
can construct a union type "Union of string or nil". To do this with a sum
type you'd have to have a common super type of string and nil _and no other
types_.

There are also intersection types, about which I know very little.

~~~
seanmcdirmid
> In a language like Python you can consider there to be one type called, say,
> ThePythonType, or which all types are a variant. Then all objects have type
> ThePythonType.

This is only if you reject the notion of a dynamic type (as most type
theorists do, but programmers do not). Otherwise, Python has a rich type
system that is checked at run-time. It lacks sum types, but we could easily
imagine a dynamically checked realization.

~~~
jlouis
A good way of getting at this is to call things at runtime "classes" or "tags"
to make it apparent that their discrimination happens at runtime, not compile-
time. The problem is that if you call both things types, you quickly run into
a situation where you are essentially talking about different concepts
entirely.

Note that most sum-types are implemented by having a runtime tag on which you
can discriminate.

~~~
seanmcdirmid
Classes exist statically also. Tags are meaningless outside of implementation
discussions.

------
_pmf_
If they say "cross product", don't they actually mean "cartesian product"?

~~~
jlouis
Beware here! There are a couple of different products you can sensibly form on
data. So you have to make it very explicit which you mean when you talk about
them. You can't generally interchange them in all contexts, but in some
contexts you definitely can.

In Type theory, the product is a product in the sense of category theory,
which is a very abstract notion of product indeed. The idea is that given
objects, here types, A and B; you can form their product, A * B and that is
also a valid object in the category. The diagram then universally identifies
the A * B element as the one where you can project out of it via the 1st and
2nd projection such the at given diagram commutes, etc. And it is important to
stress there are many products for which this property hold.

(Edited a bit to appease the automatic formatter at HN)

~~~
mmarx
Any two of those many products, however, are isomorphic, and hence, while
still distinguishable, they are “essentially” the same.

~~~
tel
If I'm reading the op right, this is incorrect. Oftentimes "products" in
various contexts are "categorical products cut down by some sensible
quotienting". In any category the categorical product will always be the
largest (this is essentially what its definition entails) and only by careful
choice of category will that correspond to some of the less formal "products"
available.

~~~
mmarx
No, altough the wording might have been misleading—I was refering to the
second paragraph, while you seem to have applied it to the first. I hope this
clarifies the situation a bit:

For any category, the product A * B of two objects A, B (if it exists) is
unique only up to isomorphism (this follows from the universal mapping
property).

In general, products A * B and C * D need not be isomorphic (and seldomly
are), and neither do products from different categories. Many of the commonly-
used products actually arise from a product in a suitable category, the
cartesian product, for example, is a product in the category of sets.

~~~
tel
Yeah I think I just misunderstood your statement: I agree with this extension
upon it completely.

------
frou_dh
Sum types with compiler-enforced exhaustive pattern matching feel like a
massive win and are the main thing I'd love to import in to traditional
procedural programming. Switch statements and their ad hoc nature pale in
comparison.

------
doctorKrieger
so the monad tutorials stopped being cool?

