ponyc icon indicating copy to clipboard operation
ponyc copied to clipboard

Compiler doesn't treat typeargs in a match as open-ended

Open jtfmumm opened this issue 9 years ago • 3 comments

The compiler should know that List[B] is a possible reification of a type A, but it currently does not. The compiler treats type variables in a match as open ended but not when they are typeargs in another type.

jtfmumm avatar Apr 09 '16 13:04 jtfmumm

Can you give an example of what you think is in error and what you believe the compiler should be doing?

SeanTAllen avatar Apr 09 '16 14:04 SeanTAllen

Here's my implementation of flatten() on a persistent List. List[A] is a type alias for (Cons[A] | Nil[A]):

fun val flatten[B](): List[B] ? =>
    match (_head, _tail)
    | (let h: List[B], let t: List[List[B]]) => _flatten[B](Cons[List[B]](h, t), Nil[B])
    else
      error
    end

Here's the compiler error:

Error:
/Users/jtfmumm/dev/pony-functional-data/src/persistent-data/list.pony:130:22: this pattern can never match
    | (let h: List[B], let t: List[List[B]]) => _flatten[B](Cons[List[B]](h, t), Nil[B])
                     ^
Error:
/Users/jtfmumm/dev/pony-functional-data/src/persistent-data/list.pony:129:17: match type: (Cons[A #any] val->val->A #any !, (Cons[A #any] val | Nil[A #any] val))
    match (_head, _tail)
                ^
Error:
/Users/jtfmumm/dev/pony-functional-data/src/persistent-data/list.pony:130:22: pattern type: ((Cons[B #any] val | Nil[B #any] val), (Cons[(Cons[B #any] val | Nil[B #any] val)] val | Nil[(Cons[B #any] val | Nil[B #any] val)] val))
    | (let h: List[B], let t: List[List[B]]) => _flatten[B](Cons[List[B]](h, t), Nil[B])

jtfmumm avatar Apr 09 '16 14:04 jtfmumm

The compiler should know that List[B] is a possible reification of A, but here it's telling us that that is not possible.

jtfmumm avatar Apr 09 '16 14:04 jtfmumm