Comparison of programming languages (algebraic data type)
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 { int value; std::unique_ptr<std::variant<Empty, Node>> left; std::unique_ptr<std::variant<Empty, Node>> right; }; using Tree = std::variant<Empty, Node>;
And instantiated as:
Tree myTree { Node{ 42, std::make_unique<Tree>(Node{ 0, std::make_unique<Tree>(), std::make_unique<Tree>() }), std::make_unique<Tree>() } };
Dart
In Dart, an ADT may be defined with:[5]
sealed class Tree {} final class Empty extends Tree {} final class Node extends Tree { final int value; final Tree left, right; Node(this.value, this.left, this.right); }
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, an ADT may be defined with:[9]
type TTreeKind = (tkEmpty, tkNode); PTree = ^TTree; TTree = record case FKind: TTreeKind of tkEmpty: (); tkNode: ( FValue: Integer; FLeft, FRight: PTree; ); end;
And instantiated as:
var MyTree: PTree; begin new(MyTree); MyTree^.FKind := tkNode; MyTree^.FValue := 42; new(MyTree^.FLeft); MyTree^.FLeft^.FKind := tkNode; MyTree^.FLeft^.FValue := 0; new(MyTree^.FLeft^.FLeft); MyTree^.FLeft^.FLeft^.FKind := tkEmpty; new(MyTree^.FLeft^.FRight); MyTree^.FLeft^.FRight^.FKind := tkEmpty; new(MyTree^.FRight); MyTree^.FRight^.FKind := tkEmpty; end.
Haskell
In Haskell, an ADT may be defined with:[10]
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:[11]
enum Tree { Empty; Node(value:Int, left:Tree, right:Tree); }
And instantiated as:
var myTree = Node(42, Node(0, Empty, Empty), Empty);
Hope
In Hope, an ADT may be defined with:[12]
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:[13]
data Tree = Empty | Node Nat Tree Tree
And instantiated as:
myTree : Tree myTree = Node 42 (Node 0 Empty Empty) Empty
Java
In Java, an ADT may be defined with:[14]
sealed interface Tree { record Empty() implements Tree {} record Node(int value, Tree left, Tree right) implements 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:[15]
struct Empty end struct Node value::Int left::Union{Empty, Node} right::Union{Empty, Node} end const Tree = Union{Empty, Node}
And instantiated as:
mytree = Node(42, Node(0, Empty(), Empty()), Empty())
Kotlin
In Kotlin, an ADT may be defined with:[16]
sealed class Tree { object Empty : Tree() data class Node(val value: Int, val left: Tree, val right: Tree) : 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:[17]
Tree: adt { pick { Empty => Node => value: int; left: ref Tree; right: ref Tree; } };
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:[18]
:- 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:[19]
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:[20]
variant Tree { | Empty | Node { value: int; left: Tree; right: 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:[21]
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:[22]
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:[23]
type tree = { empty } or { node, int value, tree left, tree right }
And instantiated as:
my_tree = { node, value: 42, left: { node, value: 0, left: { empty }, right: { empty } }, right: { empty } }
OpenCog
In OpenCog, an ADT may be defined with:[24]
PureScript
In PureScript, an ADT may be defined with:[25]
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:[26]
from __future__ import annotations from dataclasses import dataclass @dataclass class Empty: pass @dataclass class 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:[27]
(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:[28]
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:[29]
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:[30]
enum Tree { Empty, Node(i32, Box<Tree>, Box<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:[citation needed]
sealed abstract class Tree extends Product with Serializable object Tree { final case object Empty extends Tree final case class Node(value: Int, left: Tree, right: Tree) extends 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:[31]
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:[32]
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:[33]
enum Tree { case empty indirect case node(Int, Tree, Tree) }
And instantiated as:
let myTree: Tree = .node(42, .node(0, .empty, .empty), .empty)
TypeScript
In TypeScript, an ADT may be defined with:[34]
type Tree = | { kind: "empty" } | { kind: "node"; value: number; left: Tree; right: Tree };
And instantiated as:
const myTree: Tree = { kind: "node", value: 42, left: { kind: "node", value: 0, left: { kind: "empty" }, right: { kind: "empty" }, }, right: { kind: "empty" }, };
Visual Prolog
In Visual Prolog, an ADT may be defined with:[35]
domains tree = empty; node(integer, tree, tree).
And instantiated as:
constants my_tree : tree = node(42, node(0, empty, empty), empty).
References
- ↑ "Eclipse Ceylon: Union, intersection, and enumerated types". https://ceylon-lang.org/documentation/1.3/tour/types/#enumerated_types.
- ↑ "Clean 2.2 Ref Man". https://clean.cs.ru.nl/download/html_report/CleanRep.2.2_7.htm#_Toc311798039.
- ↑ "Inductive types and recursive functions — Coq 8.14.1 documentation". https://coq.inria.fr/refman/language/core/inductive.html.
- ↑ "std::variant - cppreference.com". https://en.cppreference.com/w/cpp/utility/variant.
- ↑ "Patterns" (in en). https://dart.dev/language/patterns#algebraic-data-types.
- ↑ "Custom Types · An Introduction to Elm". https://guide.elm-lang.org/types/custom_types.html.
- ↑ cartermp. "Discriminated Unions - F#" (in en-us). https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/discriminated-unions.
- ↑ "Inductive types and pattern matching — Proof-Oriented Programming in F* documentation". https://www.fstar-lang.org/tutorial/book/part1/part1_inductives.html.
- ↑ "Record types". https://www.freepascal.org/docs-html/current/ref/refsu15.html.
- ↑ "4 Declarations and Bindings". https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-690004.2.1.
- ↑ "Enum Instance". https://haxe.org/manual/types-enum-instance.html.
- ↑ "Defining your own data types". 2011-08-10. http://www.soi.city.ac.uk/~ross/Hope/hope_tut/node18.html.
- ↑ "Types and Functions — Idris2 0.0 documentation". https://idris2.readthedocs.io/en/latest/tutorial/typesfuns.html#data-types.
- ↑ "JEP 409: Sealed Classes". https://openjdk.java.net/jeps/409.
- ↑ "Types · The Julia Language". https://docs.julialang.org/en/v1/manual/types/#Type-Unions.
- ↑ "Sealed classes | Kotlin" (in en-US). https://kotlinlang.org/docs/sealed-classes.html.
- ↑ Stanley-Marbell, Phillip (2003) (in English). Inferno Programming with Limbo. Wiley. pp. 67–71. ISBN 978-0470843529.
- ↑ "The Mercury Language Reference Manual: Discriminated unions". https://www.mercurylang.org/information/doc-release/mercury_ref/Discriminated-unions.html.
- ↑ "An Overview of Miranda". https://www.cs.kent.ac.uk/people/staff/dat/miranda/Overview.html#User.
- ↑ "Basic Variants · rsdn/nemerle Wiki" (in en). https://github.com/rsdn/nemerle/wiki/Basic-Variants/4fcecdfa79c0751f70bff83225e125f40425d1f4.
- ↑ "Nim Manual". https://nim-lang.org/docs/manual.html#types-object-variants.
- ↑ "OCaml - The OCaml language". https://ocaml.org/manual/typedecl.html.
- ↑ "The type system · MLstate/opalang Wiki" (in en). https://github.com/MLstate/opalang/wiki/The-type-system/aacaf2c26b1e20189e01923cf1f9a813f355b592#sum-1.
- ↑ "Type constructor - OpenCog". https://wiki.opencog.org/w/Type_constructor.
- ↑ purescript/documentation, PureScript, 2021-11-24, https://github.com/purescript/documentation/blob/7295b335dfbda17015e68f4c74b81e91007f79b8/language/Types.md#tagged-unions, retrieved 2021-11-30
- ↑ PEP 484 – Type Hints, Python, https://peps.python.org/pep-0484/#union-types
- ↑ "2 Beginning Typed Racket". https://docs.racket-lang.org/ts-guide/beginning.html#(part._.Datatypes_and_.Unions).
- ↑ "Variants · Reason" (in en). https://reasonml.github.io/docs/en/variant.
- ↑ "Variant | ReScript Language Manual". https://rescript-lang.org/docs/manual/latest/variant.
- ↑ "enum - Rust". https://doc.rust-lang.org/std/keyword.enum.html.
- ↑ "Algebraic Data Types". https://docs.scala-lang.org/scala3/reference/enums/adts.html.
- ↑ "Defining datatypes". https://homepages.inf.ed.ac.uk/stg/NOTES/node41.html.
- ↑ "Enumerations — The Swift Programming Language (Swift 5.5)". https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html.
- ↑ "Documentation - TypeScript for Functional Programmers" (in en). https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions.
- ↑ "Language Reference/Domains - wiki.visual-prolog.com". https://wiki.visual-prolog.com/index.php?title=Language_Reference/Domains#Compound_Domains.
Original source: https://en.wikipedia.org/wiki/Comparison of programming languages (algebraic data type).
Read more |