There's a lot of type terminology and jargon going around when discussing types in Elm. This glossary attempts to list some of the most common type terms along with synonyms, terms from other language communities, examples, and links to more detailed articles on each topic.
These are the basic building blocks of data modeling in Elm. This used to be called a union type but the community moved away from that due to confusion with a different type concept of the same name found in some other languages.
People coming to Elm from other language communities may know these as sum types, algebraic data types (ADT), discriminated unions, or tagged unions (yeah these things go by a lot of different names 🤯).
The official guide has a good intro to custom types.
A type with only a single possible value. This could be a custom type, or a built-in type like the empty tuple and empty record.
-- CUSTOM TYPE
type MyUnit = MyUnit
-- EMPTY TUPLE
()
-- EMPTY RECORD
{}
When needing a type with only a single value, people commonly reach for the
empty tuple ()
, leading people to commonly refer to it as the unit type.
For more counting how many values could exist for a type, see types as sets.
This is a regular custom type wrapped around some other value, commonly a primitive. It is used to allow the compiler to know that two values represent fundamentally different quantities. This technique is especially common when dealing with units of measure or just generally trying to avoid primitive obsession.
type Dollar = Dollar Int
You'll occasionally see people refer to these as a newtype because it
behaves like what you'd get with Haskell's newtype
keyword.
These are types whose constructors are private. This allows the author to control how the type can be instantiated and how the inner data can be accessed.
-- OPAQUE
module Time exposing (Posix)
type Posix = Posix Int
-- NOT OPAQUE
module Time exposing (Posix(..))
type Posix = Posix Int
The official Elm design guidelines recommend package authors use these because it makes it easier to change a package's implementation without breaking changes for users.
Opaque types are often also used to enforce validations.
Note that opaque types combos with many other type techniques so it's possible to have an opaque unit type or an opaque wrapper type.
These are types that have a type variable but don't use it.
-- `a` IS UNUSED
type Currency a = Currency Int
They are used to let the compiler know two values represent different quantities while also letting them share common functions. More about phantom types.
- The advanced types in elm series by Charlie Koster