ponyc
ponyc copied to clipboard
Compiler doesn't treat typeargs in a match as open-ended
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.
Can you give an example of what you think is in error and what you believe the compiler should be doing?
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])
The compiler should know that List[B] is a possible reification of A, but here it's telling us that that is not possible.