Skip to content

Type System

Hazurl edited this page Jun 21, 2018 · 1 revision

Type System

The language has a strong and static type discipline.

Type definition

A type can be one of the following:

  • build-in types : unsigned/signed/floating numbers of different size
  • union : can only be one type of the set at a time
  • product : tuple-like types where a value of this type hold a value of each type of the product
  • function : transforming a type into another
  • generic : type depending on another

Example:

// Build-in types
// type Int, Float

// Union 
type A = Int | Float
-- Product
type P = Int Float Int
-- Generic
type P 'A = 'A
-- Function
type F = Int -> Float

-- Example:
-- 2D vector
type Vec2 = Float Float
-- Maybe with only types, see #Details
type Nothing
type Just 'A = 'A
type Maybe 'A = Nothing | (Just 'A)
-- Compose function type
type Compose 'A 'B 'C = ('B -> 'C) -> ('A -> 'B) -> 'A -> 'C

Build-in types

Only the necessary types are added: (U)Byte, (U)Short, (U)Int, (U)Long, Float, Double respectively 1, 2, 4, 8, 4 and 8 bytes long. The U before integers types specify unsigned version of that type.

Generic types

A generic type can be recognized by it's bound types prefixed by '. A function using those use the type inferring to determine them:

let f : 'A -> 'B  = ...;
let i : Float = f(42 as Int); 
// 'A is Int thanks to the first parameter
// 'B is Float thanks to the type of `i`

Conversion

Any Type can be implicitly casted to a union type containing this type :

type A = B | C
let b : B = ...;
let a : A = b; // implicit
let a_ : A = A(b); // explicit

Any other conversion must be explicit, either by using a function transforming the value, or by using the constructor:

type Pair = Int Int
let p : Pair = Pair(42, 1337);

The Type of a constructor is a function taking each type in the same order as defined. Union type's constructor need to be casted to use the right version :

let f = A; 
// error : Can't determined which version used : `B -> A` or `C -> A`
// note : Try to cast the constructor to the type you wants
let f : B -> A = A; 
// or
let f = A as (B -> A);

Traits

A Trait is a set of operations and functions operating in relation to a type. It's useful when an operation require the implementation of the type to be well-defined and/or the operation can't be generalized to all types.

trait Representable of 'A = // It should have at least one type binding
    toString : ('A -> String);

define Representable of Bool {
    // Implementation depending on the definition of type
    // In this case `Bool`
    toString (b : Bool) -> String { return if b then "True" else "False"; } 
}``` 

`toString` can then be used in expression: 
```hs
let str = toString(True); // "True"

A trait can be used on generics types, can require multiple operations and can provide a default value on those operations.

Constraints

When defining a generic type you probably wants to constraints this types because not all of them define a trait for example.

let toString2 : 'A -> String where Representable 'A = toString
// toString2 can only be used to type defining the `Representable` trait
Clone this wiki locally