koka-lang / koka

Koka language compiler and interpreter

Home Page:http://koka-lang.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Function types can no longer be inferred from partial signatures

anfelor opened this issue · comments

In recent versions of Koka (3.0.4 - 3.1.1), it is no longer possible to give only partial type annotations for functions. Consider the following partition function:

fun partition(p : a, xs : list<a>, ?cmp : (a, a) -> order) : (list<a>, list<a>)
  match xs
    [] -> ([], [])
    Cons(x, xx) ->
      val (lo, hi) = partition(p, xx)
      if x <= p
        then (Cons(x, lo), hi)
        else (lo, Cons(x, hi))

This function checks in Koka when all types of arguments and result are provided (as above) and if none are provided. However, omitting the type of any argument or the result type, leads to the following error message:

abstract type(s) escape(s) into the context
term         : fun partition(p, xs : list<a>, ?cmp : (a, a) -> order) : (list<a>, list<a>)
               ...
                       else (lo, Cons(x, hi))
inferred type: (p : $a, xs : list<$a>, ?cmp : ($a, $a) -> order) -> (list<$a>, list<$a>)
hint         : give a higher-rank type annotation to a function parameter?

This behaviour also occurs with functions that do not use implicit parameters, such as the following CPS-transformed map function:

fun map-cps( xs : list<a>, f : a -> b, k : list<b> -> list<b> ) : list<b>
  match xs
    Nil -> k(Nil)
    Cons(x, xx) ->
      val y = f(x)
      map-cps(xx, f, fn(ys) k(Cons(y, ys)))

Was this ever supported for partially annotated type variables?
I seem to remember running into this issue in general for type variables. Annotating concrete types has always worked, and I think continues to work.

Daan and I discussed always requiring top level type annotations for functions (due to some issues of type checking taking an exponential amount of time due to backtracking). Instead he decided to remove some of the backtracking, and more aggressively propagate annotated types down.

If this is a regression it is probably related to those changes, and not the implicit parameter changes which didn't touch the rest of the type system much.

TLDR; I'm not sure if this ever worked, and if the change was intended, but I think in general it seems that if you annotate type variables it is best to annotate them all for the whole function signature, maybe this can be a recommendation, or specifically pointed out in the documentation if this is an intended change, or the way it always has been.