Comparison of programming languages (algebraic data type)

From Wikipedia the free encyclopedia

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[edit]

Ceylon[edit]

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[edit]

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[edit]

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++[edit]

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[edit]

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[edit]

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#[edit]

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*[edit]

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[edit]

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

{$mode ISO} 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[edit]

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[edit]

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

enum Tree { 	Empty; 	Node(value:Int, left:Tree, right:Tree); } 

And instantiated as:

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

Hope[edit]

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[edit]

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

data Tree     = Empty     | Node Nat Tree Tree 

And instantiated as:

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

Java[edit]

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

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[edit]

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

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[edit]

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

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[edit]

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

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[edit]

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[edit]

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[edit]

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

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[edit]

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[edit]

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[edit]

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

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[edit]

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

PureScript[edit]

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

data Tree   = Empty   | Node Int Tree Tree 

And instantiated as:

myTree = Node 42 (Node 0 Empty Empty) Empty 

Python[edit]

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

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[edit]

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

(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[edit]

Reason[edit]

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

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

And instantiated as:

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

ReScript[edit]

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

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

And instantiated as:

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

Rust[edit]

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

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[edit]

Scala 2[edit]

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[edit]

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

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[edit]

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

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

And instantiated as:

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

Swift[edit]

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

enum Tree {     case empty     indirect case node(Int, Tree, Tree) } 

And instantiated as:

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

TypeScript[edit]

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

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[edit]

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

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

And instantiated as:

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

References[edit]

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