Types
Type annotations
Type annotations describe the type of a function or value.
// Type: |-------------------------|
function f (x: Int) (y: Int) -> Int = x + y
Local bindings can also be annotated.
let a: Int = 3;
let (b, c): (Int, Int) = (100, 200);
let (d, e): (_, Int) = (300, 400) // Inference for d, specify type for e.
Declaring data types
Type declarations are only allowed at the module level.
All types in Fuyu are algebraic data types, and more specifically, sum types. A sum type is one that can take on exactly one value from a set of possible values, which are created using value constructors. The value constructors live at the top level of the module in which they are declared.
type Size
case Small
case Medium
case Large
function default_size () -> Size = Medium
Value constructors
A value of type Size can take on exactly one of the values Small, Medium, or Large,
which are value constructors of the type.
Value constructors have only positional data associated with them.
type Order
case Tea Size String
case Coffee Size String
function black_coffee (size: Size) -> Order = Coffee size "black"
Type parameters
Types may be parameterized, and type parameters are listed after the type name. Generic type parameters begin with a lowercase letter, while concreate types begin with an uppercase letter.
type Either a b
case This a
case That b
function swap (either: Either a b) -> Either b a = match either
case This x => That x
case That x => This x
Recursive types
Types may store values that are of their own type.
For example, the Nodes of a Tree store the left subtree, the node value, and the right subtree,
while each Leaf simply stores a terminal value and ends recursion.
type Treea
case Node (Tree a) a (Tree a)
case Leaf a
// 4
// / \
// Create this tree: 2 5
// / \
// 1 3
constant tree: Tree Int = Node (Node (Leaf 1) 2 (Leaf 3)) 4 (Leaf 5)