Profile photo for Tikhon Jelvis

A sum type, also known as a tagged union, is a type that can be one of multiple possible options. Each option can carry a different type inside of it and, crucially, each option has a unique label. This means that you can use sum types to combine one of two possible different types but also that you can have two distinct possibilities with the same type.

In other words, it's a union of multiple types that also keeps track of which of the original types each value came from, even if the values can be the same.

The most general sum type is what Haskell calls Either. A value of type Either a b can be... either a or b. Fancy that. It's defined as follows:

  1. data Either a b = Left a | Right b 


We can use it if we want to either return an
Int or a String (for example, we might have internally generated ids as numbers and externally sourced ids as strings):

  1. type Id = Either String Int 


Values of type
Id have to be tagged Left or Right: Left "external name" and Right 37. However, these tags do not tell us much about what the values represent; better practice is to define your own sum type with semantic names for the tags:

  1. data Id = External String | Internal Int 


To actually
use a sum type, we have to pattern match. This means that we provide code to handle every possibility, and the language chooses the appropriate branch depending on which type of value we get:

  1. lookupId someId = case someId of 
  2. External name -> lookup name externalIds 
  3. Internal num -> internalIds ! num 

Sum types can have any number of possible cases. A common use case is to represent abstract grammars of languages. This is particularly great for implementing domain specific languages, a technique that extends far outside traditional language design. Sum types can be combined with product types (ie tuples that contain multiple values) giving us algebraic data types. Algebraic data types are a very natural way to implement grammars. Here's a simple abstract grammar for the untyped λ-calculus:


The actual code for it? A bit uglier but substantially the same:

  1. data Expr = Variable Name 
  2. | Lambda Name Expr 
  3. | App Expr Expr 


Crucially, the
shape of the grammar is preserved, which makes working with it much easier.

The possible tags in a sum type do not have to carry any additional information. (This is the same as having them carry a type with one value like ().) If none of the tags carry any additional information, the sum type is called an enum, similar to enums in languages like Java. Indeed, a reasonable way to think of sum types is as a generalization of basic enums like this.

In Swift, this is exactly how sum types are realized: they are called enumerations and use a syntax very similar to enums in Java. It's enheartening to see a popular language like Swift adopt this feature because it's simple, powerful and overlooked by most other popular languages.

In Haskell, even fundamental types like Bool are expressed as sum types:

  1. data Bool = True | False 


Yes, it's that simple! (Well, there are actually also some typeclass instances, but this fully defines the type itself.)

Sum types are useful whenever you have multiple possible cases to consider. They let you encode this possibility directly and are closed: you can't add new cases to a sum type later on. Being closed is a big advantage over other ways of encoding the same idea like inheritance because it makes the programmer's intentions clearer and lets the compiler ensure that you did not forget a case. If you pattern match on a type and don't include all the cases, you will get a compiler warning.

However, nothing about sum types fundamentally forces them to be closed. Some languages like OCaml also let you define sum types that are open: you can add new cases later on. (Actually, it's a bit more complicated than that, but that's the important idea.) In OCaml, these open types (called polymorphic variants) have constructors written with backticks like `Ok. They are kept distinct from normal closed sum types because closed sum types are help catch common errors and have marginally better performance characteristics.

One really powerful advantage of having sum types is that it means your language does not have to make every single type nullable by default. Sum types fix Tony Hoare's "billion dollar mistake". Instead of having nulls—and potentially null pointer exceptions—everywhere, we can create a single wrapper type to make any other type nullable. This is called the Option type in some languages and Maybe in Haskell:

  1. data Maybe a = Just a | Nothing 


Using this type lets the compiler warn you if a value might be null or if you forget to handle the null case. And it didn't even need a special language feature: it's an easy use of a sum type!

I've already said a lot (too much?), but I—and others—actually have more to say on sum types and algebraic types in general! Turns out it's a topic I've put more thought into than I realized. (I wrote this answer almost as fast as I can type—30-40 minutes tops. That means it was on the top of my mind at some point.)

One interesting thing is the relationship between the sum and product types that make up algebraic data types. At first, sum types might seem a bit arbitrary, but after taking a close look at their structure, we can see that they're a natural consequence of product types, present in virtually every language, through a particular sort of symmetry. I wrote a whole article about this on my company's blog: Algebraic Data Types. (While you're at it, try our maze challenge.)

Another interesting thing is that, like the name implies, we can do basic algebraic operations like addition and multiplication with algebraic data types. What's a lot more surprising is that this generalizes as far as derivation, giving us a useful construct called a zipper. This was explained neatly in a wonderful series of blog posts by Chris Taylor, The Algebra of Algebraic Data Types (based on a talk by the author).
.

View 4 other answers to this question
About · Careers · Privacy · Terms · Contact · Languages · Your Ad Choices · Press ·
© Quora, Inc. 2025