a
, we are assigning it a type parameter b
. Now, what is the type of method succ
on a type b
? We can never know, as it depends on the implementation of a particular class that will be used. Hence, the type of callSucc
is simply b -> b.succ
. You can read it as "a function that takes an argument of type b
and returns whatever the method succ
of class b
returns". We can now write callSucc 1
, since the succ
method is defined for Int
s, but callSucc "hello"
will result in a compile error.+
operator is defined in Luna standard library as:5 + 7
or "foo" + "bar"
, but will reject "foo" + 5
(because arguments' types are different) or Just 5 + Just 7
(because the +
method is not defined for the Maybe
class). So what is really going on here?+
indicates that the type a
needs to have this method defined. Moreover, this method needs to take a single argument of type a
and return a result also of type a
. All this allows us to describe the type of function +
as:a
such that a.+ = a -> a
def foo x: x.succ + 1
x.succ
is added to an Int
, so (from the definition of +
above) we know that x.succ :: Int
and that the result of this function is also an Int
. So the final type with the underlying assumptions is:a
such that a.succ = Int