8.1 Constructors
When we're introducing a new type such as myint
, we often need to provide
a way to convert to and from other types. We can do this as so:
type myint = "int"; fun make_myint: int -> myint = "$1"; fun make_int: myint -> int = "$1"; var x : myint = make_myint (42); println$ make_int(x);
42
Since int
and myint
share the same C++ representation, the
conversions are the identity in this case. However it's a bit hard to remember
the names of the constructors.
Felix allows you to use the type name, like C++, you can make this happen like this:
fun _ctor_myint : int -> myint = "$1"; fun _ctor_int : myint -> int = "$1"; var y : myint = myint (42); println$ int(y);
42
This is a bit clumsy and repeats the typename in the function name and the return type, so there's a more readable shorthand:
type yourint = "int"; ctor yourint : int = "$1"; ctor int : yourint = "$1"; var z = yourint (42); println$ int(z);
42
This removes the duplication with the _ctor_
notation but
it equivalent.
When Felix is looking up a function and it finds a type
name T, it will try to find the function _ctor_T
instead.
You know you can overload constructors because they're just ordinary
function bindings.
You can also use a typedef name:
typedef alias = myint; ctor alias : double = "int($1)"; println$ int ( alias (4.2) );
4
This works because the translation rule says typename, which includes aliases.