ExpandCollapsePrev Next Index

+ 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.