Lack of type refinement for match case
See original GitHub issueCompiler version
3.1.3
Minimized code
sealed trait NatT
case class Zero() extends NatT
case class Succ[N<: NatT](n: N) extends NatT
trait IsLessThan[M <: NatT, N <: NatT]
object IsLessThan:
given base[M <: NatT]: IsLessThan[M, Succ[M]]()
given weakening[N <: NatT, M <: NatT] (using IsLessThan[N, M]): IsLessThan[N, Succ[M]]()
given reduction[N <: NatT, M <: NatT] (using IsLessThan[Succ[N], Succ[M]]): IsLessThan[N, M]()
sealed trait UniformTuple[Length <: NatT, T]:
def apply[M <: NatT](m: M)(using IsLessThan[M, Length]): T
case class Empty[T]() extends UniformTuple[Zero, T]:
def apply[M <: NatT](m: M)(using IsLessThan[M, Zero]): T = throw new AssertionError("Uncallable")
case class Cons[N <: NatT, T](head: T, tail: UniformTuple[N, T]) extends UniformTuple[Succ[N], T]:
def apply[M <: NatT](m: M)(using proof: IsLessThan[M, Succ[N]]): T = m match
case Zero() => head
case Succ(predM): Succ[predM] => tail(predM)(using IsLessThan.reduction(using proof))
Output
Found: (proof : IsLessThan[M, Succ[N]])
Required: IsLessThan[Succ[predM], Succ[N]]
Expectation
The code is expected to compile, as within that case branch, M
is identified with Succ[predM]
.
I opened a discussion thread on contributors.scala-lang.org about this, but didn’t get any answer. So I’m tentatively filing this as a bug.
Issue Analytics
- State:
- Created a year ago
- Comments:14 (6 by maintainers)
Top Results From Across the Web
Practical Refinement-Type Checking
Abstract. Refinement types allow many more properties of programs to be expressed and statically checked than conventional type systems.
Read more >1 Refinement Types
Type refinement systems are conservative: they preserve the properties of the underlying type system. The framework to be presented as- sumes the existing...
Read more >Request: allow refinement types · Issue #560 · python/mypy
Please consider allowing: Refine[C, f] to be used as a type, where C is a type and f is consistent with: C ->...
Read more >Principles of Type Refinement (OPLSS 2016) - Noam Zeilberger
1.1 What is a type refinement system? Since type systems are so useful, it would be nice if we could say exactly what....
Read more >Focusing on Liquid Refinement Typing - arXiv
ordinary recursive programs at all in our type refinements. ... constructing refined inductive values, pattern matching on refined inductive ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@Linyxus This is great. Now that I know about it and once the PR is in, I can make use of this pattern.
I do wonder how many people would find such a solution when in a similar situation. I know that I would never have come up with this by myself. I guess documentation can go a long way.
Currently in #14754 we only record equalities between singleton types. So we will not record a constraint like
m.type <: Succ[predM]
. However, by rewriting the example a bit:we will be able to record the equality
m.type == m1.type
. But this still cannot make the example work. The furthest i can go is:The last line still cannot typecheck because what we want here is a
IsLessThan[Succ[predM.type], Succ[N]]
, but what we have isIsLessThan[Succ[predM], Succ[N]]
. (note that to allow theval proof2
line typecheck we have to make the first type parameter ofIsLessThan
covariant, since the widen type ofm1.type
isM & Succ[predM]
).