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.
In ATS, an ADT may be defined with: [1] [2]
datatypetree=|Emptyof()|Nodeof(int,tree,tree)And instantiated as:
valmy_tree=Node(42,Node(0,Empty,Empty),Empty)Additionally in ATS dataviewtypes are the linear type version of ADTs for the purpose of providing in the setting of manual memory management with the convenience of pattern matching. [3] An example program might look like:
(* Alternatively one can use the datavtype keyword *)dataviewtypeint_or_string_vt(bool)=|String_vt(true)ofstring|Int_vt(false)ofint(* Alternatively one can use the vtypedef keyword *)viewtypedefInt_or_String_vt=[b:bool]int_or_string_vtbfnprint_int_or_string(i_or_s:Int_or_String_vt):void=case+i_or_sof(* ~ indicates i_or_s will be implicitly freed in this case *)|~String_vt(s)=>println!(s)(* @ indicates i_or_s must be explicitly freed in this case *)|@Int_vt(i)=>begin$extfcall(void,"fprintf",stdout_ref,"%d\n",i);free@i_or_s;endimplementmain0():void=letvalstring_hello_world=String_vt"Hello, world!"valint_0=Int_vt0inprint_int_or_stringstring_hello_world;print_int_or_stringint_0;(* which prints: Hello, world! 0 *)endIn Ceylon, an ADT may be defined with: [4]
abstractclassTree()ofempty|Node{}objectemptyextendsTree(){}finalclassNode(sharedIntegerval,sharedTreeleft,sharedTreeright)extendsTree(){}And instantiated as:
valuemyTree=Node(42,Node(0,empty,empty),empty);In Clean, an ADT may be defined with: [5]
::Tree=Empty|NodeIntTreeTreeAnd instantiated as:
myTree=Node42(Node0EmptyEmpty)EmptyIn C++, an ADT may be defined with: [6]
structEmptyfinal{};structNodefinal{intvalue;std::unique_ptr<std::variant<Empty,Node>>left;std::unique_ptr<std::variant<Empty,Node>>right;};usingTree=std::variant<Empty,Node>;And instantiated as:
TreemyTree{Node{42,std::make_unique<Tree>(Node{0,std::make_unique<Tree>(),std::make_unique<Tree>()}),std::make_unique<Tree>()}};In Dart, an ADT may be defined with: [7]
sealedclassTree{}finalclassEmptyextendsTree{}finalclassNodeextendsTree{finalintvalue;finalTreeleft,right;Node(this.value,this.left,this.right);}And instantiated as:
finalmyTree=Node(42,Node(0,Empty(),Empty()),Empty());In Elm, an ADT may be defined with: [8]
typeTree=Empty|NodeIntTreeTreeAnd instantiated as:
myTree=Node42(Node0EmptyEmpty)EmptyIn F#, an ADT may be defined with: [9]
typeTree=|Empty|Nodeofint*Tree*TreeAnd instantiated as:
letmyTree=Node(42,Node(0,Empty,Empty),Empty)In F*, an ADT may be defined with: [10]
typetree=|Empty:tree|Node:value:nat->left:tree->right:tree->treeAnd instantiated as:
letmy_tree=Node42(Node0EmptyEmpty)EmptyIn Free Pascal (in standard ISO Pascal mode [11] ), an ADT may be defined with variant records: [12]
{$mode ISO}programMakeTree;typeTreeKind=(Empty,Node);PTree=^Tree;Tree=recordcaseKind:TreeKindofEmpty:();Node:(Value:Integer;Left,Right:PTree;);end;And instantiated as:
varMyTree:PTree;beginnew(MyTree,Node);withMyTree^dobeginValue:=42;new(Left,Node);withLeft^dobeginValue:=0;new(Left,Empty);new(Right,Empty);end;new(Right,Empty);end;end.In Haskell, an ADT may be defined with: [13]
dataTree=Empty|NodeIntTreeTreeAnd instantiated as:
myTree=Node42(Node0EmptyEmpty)EmptyIn Haxe, an ADT may be defined with: [14]
enumTree{Empty;Node(value:Int,left:Tree,right:Tree);}And instantiated as:
varmyTree=Node(42,Node(0,Empty,Empty),Empty);In Hope, an ADT may be defined with: [15]
datatree==empty++node(num#tree#tree);And instantiated as:
dec mytree : tree; --- mytree <= node (42, node (0, empty, empty), empty); In Idris, an ADT may be defined with: [16]
dataTree=Empty|NodeNatTreeTreeAnd instantiated as:
myTree:Tree myTree=Node42(Node0EmptyEmpty)EmptyIn Java, an ADT may be defined with: [17]
sealedinterfaceTree{recordEmpty()implementsTree{}recordNode(intvalue,Treeleft,Treeright)implementsTree{}}And instantiated as:
varmyTree=newTree.Node(42,newTree.Node(0,newTree.Empty(),newTree.Empty()),newTree.Empty());In Julia, an ADT may be defined with: [18]
structEmptyendstructNodevalue::Intleft::Union{Empty,Node}right::Union{Empty,Node}endconstTree=Union{Empty,Node}And instantiated as:
mytree=Node(42,Node(0,Empty(),Empty()),Empty())In Kotlin, an ADT may be defined with: [19]
sealedclassTree{objectEmpty:Tree()dataclassNode(valvalue:Int,valleft:Tree,valright:Tree):Tree()}And instantiated as:
valmyTree=Tree.Node(42,Tree.Node(0,Tree.Empty,Tree.Empty),Tree.Empty,)In Limbo, an ADT may be defined with: [20]
Tree:adt{pick{Empty=>Node=>value:int;left:refTree;right:refTree;}};And instantiated as:
myTree:=refTree.Node(42,refTree.Node(0,refTree.Empty(),refTree.Empty()),refTree.Empty());In Mercury, an ADT may be defined with: [21]
:- type tree ---> empty ; node(int, tree, tree). And instantiated as:
:- func my_tree = tree. my_tree = node(42, node(0, empty, empty), empty). In Miranda, an ADT may be defined with: [22]
tree::=Empty|NodenumtreetreeAnd instantiated as:
my_tree=Node42(Node0EmptyEmpty)EmptyIn Nemerle, an ADT may be defined with: [23]
variantTree{|Empty|Node{value:int;left:Tree;right:Tree;}}And instantiated as:
defmyTree=Tree.Node(42,Tree.Node(0,Tree.Empty(),Tree.Empty()),Tree.Empty(),);In Nim, an ADT may be defined with: [24]
typeTreeKind=enumtkEmptytkNodeTree=refTreeObjTreeObj=objectcasekind:TreeKindoftkEmpty:discardoftkNode:value:intleft,right:TreeAnd instantiated as:
letmyTree=Tree(kind:tkNode,value:42,left:Tree(kind:tkNode,value:0,left:Tree(kind:tkEmpty),right:Tree(kind:tkEmpty)),right:Tree(kind:tkEmpty))In OCaml, an ADT may be defined with: [25]
typetree=|Empty|Nodeofint*tree*treeAnd instantiated as:
letmy_tree=Node(42,Node(0,Empty,Empty),Empty)In Opa, an ADT may be defined with: [26]
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 }}| | This section needs expansion. You can help by adding to it. (December 2021) |
In OpenCog, an ADT may be defined with: [27]
In PureScript, an ADT may be defined with: [28]
dataTree=Empty|NodeIntTreeTreeAnd instantiated as:
myTree=Node42(Node0EmptyEmpty)EmptyIn Python, an ADT may be defined with: [29] [30]
from__future__importannotationsfromdataclassesimportdataclass@dataclassclassEmpty:pass@dataclassclassNode:value:intleft:Treeright:TreeTree=Empty|NodeAnd instantiated as:
my_tree=Node(42,Node(0,Empty(),Empty()),Empty())In Typed Racket, an ADT may be defined with: [31]
(structEmpty())(structNode([value:Integer][left:Tree][right:Tree]))(define-typeTree(UEmptyNode))And instantiated as:
(definemy-tree(Node42(Node0(Empty)(Empty))(Empty)))In Reason, an ADT may be defined with: [32]
typeTree=|Empty|Node(int,Tree,Tree);And instantiated as:
letmyTree=Node(42,Node(0,Empty,Empty),Empty);In ReScript, an ADT may be defined with: [33]
typerecTree=|Empty|Node(int,Tree,Tree)And instantiated as:
letmyTree=Node(42,Node(0,Empty,Empty),Empty)In Rocq, an ADT may be defined with: [34]
Inductivetree:Type:=|empty:tree|node:nat->tree->tree->tree.And instantiated as:
Definitionmy_tree:=node42(node0emptyempty)empty.In Rust, an ADT may be defined with: [35]
enumTree{Empty,Node(i32,Box<Tree>,Box<Tree>),}And instantiated as:
letmy_tree=Tree::Node(42,Box::new(Tree::Node(0,Box::new(Tree::Empty),Box::new(Tree::Empty)),Box::new(Tree::Empty),);In Scala 2, an ADT may be defined with:[ citation needed ]
sealedabstractclassTreeextendsProductwithSerializableobjectTree{finalcaseobjectEmptyextendsTreefinalcaseclassNode(value:Int,left:Tree,right:Tree)extendsTree}And instantiated as:
valmyTree=Tree.Node(42,Tree.Node(0,Tree.Empty,Tree.Empty),Tree.Empty)In Scala 3, an ADT may be defined with: [36]
enumTree:caseEmptycaseNode(value:Int,left:Tree,right:Tree)And instantiated as:
valmyTree=Tree.Node(42,Tree.Node(0,Tree.Empty,Tree.Empty),Tree.Empty)In Standard ML, an ADT may be defined with: [37]
datatypetree=EMPTY|NODEofint*tree*treeAnd instantiated as:
valmyTree=NODE(42,NODE(0,EMPTY,EMPTY),EMPTY)In Swift, an ADT may be defined with: [38]
enumTree{caseemptyindirectcasenode(Int,Tree,Tree)}And instantiated as:
letmyTree:Tree=.node(42,.node(0,.empty,.empty),.empty)In TypeScript, an ADT may be defined with: [39]
typeTree=|{kind:"empty"}|{kind:"node";value:number;left:Tree;right:Tree};And instantiated as:
constmyTree:Tree={kind:"node",value:42,left:{kind:"node",value:0,left:{kind:"empty"},right:{kind:"empty"},},right:{kind:"empty"},};In Visual Prolog, an ADT may be defined with: [40]
domainstree=empty;node(integer,tree,tree).And instantiated as:
constantsmy_tree:tree=node(42,node(0,empty,empty),empty).In Zig, an ADT may be defined with: [41]
constTree=union(enum){empty,node:struct{value:i32,left:*constTree,right:*constTree,},};And instantiated as:
constmy_tree:Tree=.{.node=.{.value=42,.left=&.{.node=.{.value=0,.left=&.empty,.right=&.empty,}},.right=&.empty,}};