A Tour of Morfa

Class and struct templates

Our running example will be a list data structure for storing a sequence of elements of some specified type T:

public template <T>
class List
{
    private var elem: T;
    private var next: List<T>;

    // Creates a new list with a specified head element
    // and a specified tail list.
    public func new(head: T, tail: List<T>)
    {
        elem = head;
        next = tail;
    }

    public property head(): T
    {
        return elem;
    }

    public property tail(): List<T>
    {
        return next;
    }
}

unittest
{
    // create a list of three integers [1,2,3]
    var ints = new List<int>(1, new List<int>(2, new List<int>(3, null)));
    assert (ints.tail.head == 2);
}

As seen above, using the full List<int> as the type name is a bit cumbersome. Things get slightly better if we introduce an alias:

public alias Ints = List<int>;

unittest
{
    var ints = new Ints(1, new Ints(2, new Ints(3, null)));
}

An even better solution would be to use a factory function instead of a constructor, taking advantage of template argument deduction for functions, as we will see in the section on function templates.

Similarly, a Pair structure holding two values of types T and U, respectively, may be defined as a struct template:

public template <T, U>
struct Pair
{
    public var fst: T;
    public var snd: U;
}

// Create an alias for the type Pair<float,float>;
public alias Point = Pair<float,float>;

unittest
{
    var pair = Pair<text,int>("morfa", 5);
    var pair2 = Pair<Pair<text,int>,bool>(pair, true);

    var pt = Point(0.1, -0.2);
}