Road to Haskeller #17 - data, type, newtype

Last Edited: 7/11/2024

The blog post introduces confusing concepts, data, type, and newtype in Haskell.

Haskell & Types

Recap

A while ago in "Road to Haskeller #8 - Datatypes," we discussed how to define a new data type like the following:

data Tree a =
    Leaf | Node (Tree a) a (Tree a)

(If you are not confident about this topic, please review the material before we move forward. ) However, there are similar concepts in Haskell: type and newtype. How do they differ from data?

Type Synonym

In many languages, String and [Char] are equivalent or synonymous. Haskell is no exception, where String is defined as synonym of [Char] in Haskell as follows.

type String = [Char]

The syntax might be misleading because type does not create a new type; it simply provides a synonym for an existing type. This synonym can simplify code and enhance readability. Type synonyms can also have parameters:

type AssocList k v = [(k, v)]

Isomorphism

There is a very similar syntax, newtype. What does it do exactly? Well, it is just like a data constructor that strictly has only one constructor and one field. Here's an example of how newtype can be used:

newtype Name = Name String

Instead of type, newtype actually creates a new data type based on an existing one. Why is this useful when we already have data? It's because newtype guarantees that the new type and the type of its field are directly corresponding, which we call isomorphic. At compile time, new types created with newtype are checked, but at runtime, new types are ignored, meaning there is no unwrapping of data inside when performing pattern matching.

Exercises

This is an exercise section where you can test your understanding of the material introduced in the article. I highly recommend solving these questions by yourself after reading the main part of the article. You can click on each question to see its answer.

Resources