Comparison of programming languages (algebraic data type) explained

This article compares the syntax for defining and instantiating an algebraic data type (ADT), sometimes also referred to as a tagged union, in various programming languages.

Examples of algebraic data types

Ceylon

In Ceylon, an ADT may be defined with:[1]

abstract class Tree of empty | Node

object empty extends Tree

final class Node(shared Integer val, shared Tree left, shared Tree right) extends Tree

And instantiated as:

value myTree = Node(42, Node(0, empty, empty), empty);

Clean

In Clean, an ADT may be defined with:[2]

Tree = Empty | Node Int Tree Tree

And instantiated as:

myTree = Node 42 (Node 0 Empty Empty) Empty

Coq

In Coq, an ADT may be defined with:[3]

Inductive tree : Type :=| empty : tree| node : nat -> tree -> tree -> tree.

And instantiated as:

Definition my_tree := node 42 (node 0 empty empty) empty.

C++

In C++, an ADT may be defined with:[4]

struct Empty final ;

struct Node final ;

using Tree = std::variant;

And instantiated as:

Tree myTree ;

Dart

In Dart, an ADT may be defined with:[5]

sealed class Tree

final class Empty extends Tree

final class Node extends Tree

And instantiated as:

final myTree = Node(42, Node(0, Empty, Empty), Empty);

Elm

In Elm, an ADT may be defined with:[6]

type Tree = Empty | Node Int Tree Tree

And instantiated as:

myTree = Node 42 (Node 0 Empty Empty) Empty

F#

In F#, an ADT may be defined with:[7]

type Tree = | Empty | Node of int * Tree * Tree

And instantiated as:

let myTree = Node(42, Node(0, Empty, Empty), Empty)

F*

In F*, an ADT may be defined with:[8]

type tree = | Empty : tree | Node : value:nat -> left:tree -> right:tree -> tree

And instantiated as:

let my_tree = Node 42 (Node 0 Empty Empty) Empty

Free Pascal

In Free Pascal (in standard ISO Pascal mode[9]), an ADT may be defined with variant records:[10]

program MakeTree;

type TreeKind = (Empty, Node); PTree = ^Tree; Tree = record case Kind: TreeKind of Empty: ; Node: (Value: Integer; Left, Right: PTree;); end;

And instantiated as:

var MyTree: PTree;

begin new(MyTree, Node); with MyTree^ do begin Value := 42; new(Left, Node); with Left^ do begin Value := 0; new(Left, Empty); new(Right, Empty); end; new(Right, Empty); end;end.

Haskell

In Haskell, an ADT may be defined with:[11]

data Tree = Empty | Node Int Tree Tree

And instantiated as:

myTree = Node 42 (Node 0 Empty Empty) Empty

Haxe

In Haxe, an ADT may be defined with:[12]

enum Tree

And instantiated as:

var myTree = Node(42, Node(0, Empty, Empty), Empty);

Hope

In Hope, an ADT may be defined with:[13]

data tree

empty ++ node (num # tree # tree);

And instantiated as:

dec mytree : tree;--- mytree <= node (42, node (0, empty, empty), empty);

Idris

In Idris, an ADT may be defined with:[14]

data Tree = Empty | Node Nat Tree Tree

And instantiated as:

myTree : TreemyTree = Node 42 (Node 0 Empty Empty) Empty

Java

In Java, an ADT may be defined with:[15]

sealed interface Tree

And instantiated as:

var myTree = new Tree.Node(42, new Tree.Node(0, new Tree.Empty, new Tree.Empty), new Tree.Empty);

Julia

In Julia, an ADT may be defined with:[16]

struct Emptyend

struct Node value::Int left::Union right::Unionend

const Tree = Union

And instantiated as:

mytree = Node(42, Node(0, Empty, Empty), Empty)

Kotlin

In Kotlin, an ADT may be defined with:[17]

sealed class Tree

And instantiated as:

val myTree = Tree.Node(42, Tree.Node(0, Tree.Empty, Tree.Empty), Tree.Empty,)

Limbo

In Limbo, an ADT may be defined with:[18]

Tree: adt ;

And instantiated as:

myTree := ref Tree.Node(42, ref Tree.Node(0, ref Tree.Empty, ref Tree.Empty), ref Tree.Empty);

Mercury

In Mercury, an ADT may be defined with:[19]

- type tree ---> empty ; node(int, tree, tree).

And instantiated as:

- func my_tree = tree.my_tree = node(42, node(0, empty, empty), empty).

Miranda

In Miranda, an ADT may be defined with:[20]

tree ::= Empty | Node num tree tree

And instantiated as:

my_tree = Node 42 (Node 0 Empty Empty) Empty

Nemerle

In Nemerle, an ADT may be defined with:[21]

variant Tree

And instantiated as:

def myTree = Tree.Node(42, Tree.Node(0, Tree.Empty, Tree.Empty), Tree.Empty,);

Nim

In Nim, an ADT may be defined with:[22]

type TreeKind = enum tkEmpty tkNode

Tree = ref TreeObj

TreeObj = object case kind: TreeKind of tkEmpty: discard of tkNode: value: int left, right: Tree

And instantiated as:

let myTree = Tree(kind: tkNode, value: 42, left: Tree(kind: tkNode, value: 0, left: Tree(kind: tkEmpty), right: Tree(kind: tkEmpty)), right: Tree(kind: tkEmpty))

OCaml

In OCaml, an ADT may be defined with:[23]

type tree = | Empty | Node of int * tree * tree

And instantiated as:

let my_tree = Node (42, Node (0, Empty, Empty), Empty)

Opa

In Opa, an ADT may be defined with:[24]

type tree = or

And instantiated as:

my_tree =

OpenCog

In OpenCog, an ADT may be defined with:[25]

PureScript

In PureScript, an ADT may be defined with:

data Tree = Empty | Node Int Tree Tree

And instantiated as:

myTree = Node 42 (Node 0 Empty Empty) Empty

Python

In Python, an ADT may be defined with:

from __future__ import annotationsfrom dataclasses import dataclass

@dataclassclass Empty: pass

@dataclassclass Node: value: int left: Tree right: Tree

Tree = Empty | Node

And instantiated as:

my_tree = Node(42, Node(0, Empty, Empty), Empty)

Racket

In Typed Racket, an ADT may be defined with:[26]

(struct Empty)(struct Node ([value : Integer] [left : Tree] [right : Tree]))(define-type Tree (U Empty Node))

And instantiated as:

(define my-tree (Node 42 (Node 0 (Empty) (Empty)) (Empty)))

Reason

Reason

In Reason, an ADT may be defined with:[27]

type Tree = | Empty | Node(int, Tree, Tree);

And instantiated as:

let myTree = Node(42, Node(0, Empty, Empty), Empty);

ReScript

In ReScript, an ADT may be defined with:[28]

type rec Tree = | Empty | Node(int, Tree, Tree)

And instantiated as:

let myTree = Node(42, Node(0, Empty, Empty), Empty)

Rust

In Rust, an ADT may be defined with:[29]

enum Tree

And instantiated as:

let my_tree = Tree::Node(42, Box::new(Tree::Node(0, Box::new(Tree::Empty), Box::new(Tree::Empty)), Box::new(Tree::Empty),);

Scala

Scala 2

In Scala 2, an ADT may be defined with:

sealed abstract class Tree extends Product with Serializable

object Tree

And instantiated as:

val myTree = Tree.Node(42, Tree.Node(0, Tree.Empty, Tree.Empty), Tree.Empty)

Scala 3

In Scala 3, an ADT may be defined with:[30]

enum Tree: case Empty case Node(value: Int, left: Tree, right: Tree)

And instantiated as:

val myTree = Tree.Node(42, Tree.Node(0, Tree.Empty, Tree.Empty), Tree.Empty)

Standard ML

In Standard ML, an ADT may be defined with:[31]

datatype tree = EMPTY | NODE of int * tree * tree

And instantiated as:

val myTree = NODE (42, NODE (0, EMPTY, EMPTY), EMPTY)

Swift

In Swift, an ADT may be defined with:[32]

enum Tree

And instantiated as:

let myTree: Tree = .node(42, .node(0, .empty, .empty), .empty)

TypeScript

In TypeScript, an ADT may be defined with:[33]

type Tree = | | ;

And instantiated as:

const myTree: Tree = ;

Visual Prolog

In Visual Prolog, an ADT may be defined with:[34]

domains tree = empty; node(integer, tree, tree).

And instantiated as:

constants my_tree : tree = node(42, node(0, empty, empty), empty).

Notes and References

  1. Web site: Eclipse Ceylon: Union, intersection, and enumerated types. 2021-11-29. ceylon-lang.org. https://web.archive.org/web/20221226095943/https://ceylon-lang.org/documentation/1.3/tour/types/#enumerated_types. 2022-12-26.
  2. Web site: Clean 2.2 Ref Man. 2021-11-29. clean.cs.ru.nl.
  3. Web site: Inductive types and recursive functions — Coq 8.14.1 documentation. 2021-11-30. coq.inria.fr.
  4. Web site: std::variant - cppreference.com. 2021-12-04. en.cppreference.com.
  5. Web site: Patterns . 2023-09-28 . dart.dev . en.
  6. Web site: Custom Types · An Introduction to Elm. 2021-11-29. guide.elm-lang.org.
  7. Web site: cartermp. Discriminated Unions - F#. 2021-11-29. docs.microsoft.com. en-us.
  8. Web site: Inductive types and pattern matching — Proof-Oriented Programming in F* documentation. 2021-12-06. www.fstar-lang.org.
  9. Web site: Mode iso . 2024-05-26 . wiki.freepascal.org.
  10. Web site: Record types . 2021-12-05 . www.freepascal.org.
  11. Web site: 4 Declarations and Bindings. 2021-12-07. www.haskell.org.
  12. Web site: Enum Instance. 2021-11-29. Haxe - The Cross-platform Toolkit.
  13. Web site: 2011-08-10. Defining your own data types. 2021-12-03. https://web.archive.org/web/20110810074239/http://www.soi.city.ac.uk/~ross/Hope/hope_tut/node18.html. 2011-08-10.
  14. Web site: Types and Functions — Idris2 0.0 documentation. 2021-11-30. idris2.readthedocs.io.
  15. Web site: JEP 409: Sealed Classes. 2021-12-05. openjdk.java.net.
  16. Web site: Types · The Julia Language. 2021-12-03. docs.julialang.org.
  17. Web site: Sealed classes Kotlin. 2021-11-29. Kotlin Help. en-US.
  18. Book: Stanley-Marbell, Phillip. Inferno Programming with Limbo. Wiley. 2003. 978-0470843529. 67–71. English.
  19. Web site: The Mercury Language Reference Manual: Discriminated unions. 2021-12-07. www.mercurylang.org.
  20. Web site: An Overview of Miranda. 2021-12-04. www.cs.kent.ac.uk.
  21. Web site: Basic Variants · rsdn/nemerle Wiki. 2021-12-03. GitHub. en.
  22. Web site: Nim Manual. 2021-11-29. nim-lang.org.
  23. Web site: OCaml - The OCaml language. 2021-12-07. ocaml.org.
  24. Web site: The type system · MLstate/opalang Wiki. 2021-12-07. GitHub. en.
  25. Web site: Type constructor - OpenCog. 2021-12-07. wiki.opencog.org.
  26. Web site: 2 Beginning Typed Racket. 2021-12-04. docs.racket-lang.org.
  27. Web site: Variants · Reason. 2021-11-30. reasonml.github.io. en.
  28. Web site: Variant ReScript Language Manual. 2021-11-30. ReScript Documentation.
  29. Web site: enum - Rust. 2021-11-29. doc.rust-lang.org.
  30. Web site: Algebraic Data Types. 2021-11-29. Scala Documentation.
  31. Web site: Defining datatypes. 2021-12-01. homepages.inf.ed.ac.uk.
  32. Web site: Enumerations — The Swift Programming Language (Swift 5.5). 2021-11-29. docs.swift.org.
  33. Web site: Documentation - TypeScript for Functional Programmers. 2021-11-29. www.typescriptlang.org. en.
  34. Web site: Language Reference/Domains - wiki.visual-prolog.com. 2021-12-07. wiki.visual-prolog.com.