From Textbook: Advanced Data Types
Algebraic Data Types
以前我们的 variants 比较像 enum
,但是现在我们更像一个abstract class
1 | (*definition*) |
examples:
1 | type point = float * float |
When do we need [],(),{} | of
?
1 | type node = {value:int; next:mylist} |
[]
: list()
: Constructor of a tuple{}
: Constructor of a record|
: delineate different variants inside a typeof
: defining the construction of an algebraic type
Recursive Variants
1 | type intlist = Nil | Cons of int * intlist |
Parametrized Variants
No matter what kind of types we define, either a variant, a record, or a tuple. We need the type parameter 'a or ('a,'b)
when we define it.
1 | (* [Option] makes it safer to return nothing*) |
Similarly, when you want to declare a variable that has a parametrized type, you also need to give the type parameter.
1 | type 'a tree = Leaf of 'a | Node of ('a * 'a tree * 'a tree) |
If you do let x:tree = Leaf 5
, the compiler won’t know what type you are talking about.
Polymorphic Variants
They would be better off with the name “anonymous variants,” because you want to use them when these variants are only used in this specific function and not anywhere else.
The constructor of polymorphic variants start with a “ ` “
1 | (* note: no type definition *) |
Pattern Matching
1 | type 'a tree = |
Exceptions
The Basics
1 | (*Definition: it is just a special kind of "type"*) |
Pattern Matching
The following code says: try evaluating e
. If it produces an exception packet, use the exception patterns from the original match expression to handle that packet. If it doesn’t produce an exception packet but instead produces a normal value, use the non-exception patterns from the original match expression to match that value.
1 | match |