question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Match type not simplified in return position

See original GitHub issue

Compiler version

3.1.1, 3.1.2-RC1

Minimized code

import scala.compiletime.ops.int.*

type Fill[N <: Int, A] <: Tuple = N match {
  case 0 => EmptyTuple
  case S[n] => A *: Fill[n, A]
}

sealed trait SeqToTuple[N <: Int] {
  def apply[A](s: Seq[A]): Fill[N, A]
}
implicit val emptyToZero: SeqToTuple[0] = new SeqToTuple[0] {
  override def apply[A](s: Seq[A]): EmptyTuple = EmptyTuple
}
implicit def successorToSuccessor[N <: Int](implicit pred: SeqToTuple[N]): SeqToTuple[S[N]] = new SeqToTuple[S[N]] {
  override def apply[A](s: Seq[A]): Fill[S[N], A] =
    s.head *: pred(s.tail) // Scala doesn't know that `A *: Fill[N, A]` = `Fill[S[N], A]` for some reason
}

Output

Found:    A *: Fill[N, A]
Required: Fill[compiletime.ops.int.S[N], A]

where:    N is a type in method successorToSuccessor with bounds <: Int

Expectation

Scala recognizes that Fill[S[N], A] = A *: Fill[N, A] (as it is a case of the match type) and lets the program compile.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:15 (12 by maintainers)

github_iconTop GitHub Comments

2reactions
bishaboshacommented, Feb 25, 2022

I think really the issue is that 0 and S[n] are not treated like independent class types, for example, if we substitute Int for some Nat enum then the example works unchanged:

enum Nat {
  case Zero
  case Succ[N <: Nat](pred: N)
}

object Nat {
  type FromInt[I <: Int] <: Nat = I match {
    case 0 => Nat.Zero.type
    case compiletime.ops.int.S[n] => Nat.Succ[FromInt[n]] 
  }
}

/// begin of example

import scala.compiletime.ops.int.*

type Fill[N <: Nat, A] <: Tuple = N match {
  case Nat.Zero.type => EmptyTuple
  case Nat.Succ[n] => A *: Fill[n, A]
}

sealed trait SeqToTuple[N <: Nat] {
  def apply[A](s: Seq[A]): Fill[N, A]
}
implicit val emptyToZero: SeqToTuple[Nat.Zero.type] = new SeqToTuple[Nat.Zero.type] {
  override def apply[A](s: Seq[A]): EmptyTuple = EmptyTuple
}
implicit def successorToSuccessor[N <: Nat](implicit pred: SeqToTuple[N]): SeqToTuple[Nat.Succ[N]] = new SeqToTuple[Nat.Succ[N]] {
  override def apply[A](s: Seq[A]): Fill[Nat.Succ[N], A] =
    s.head *: pred(s.tail) // Scala doesn't know that `A *: Fill[N, A]` = `Fill[S[N], A]` for some reason
}
                                                                                                                                                    
// scala> summon[SeqToTuple[Nat.FromInt[3]]](List(1,2,3,4,5))
// val res1: Int *: Int *: Int *: EmptyTuple = (1,2,3)
0reactions
s5bugcommented, Feb 25, 2022

Awesome! Thanks for the insights.

Read more comments on GitHub >

github_iconTop Results From Across the Web

INDEX & MATCH Functions Combo in Excel (10 Easy ...
INDEX MATCH is a powerful combination that allows you to do simple and advanced lookups in Excel. In this article, I'll show you...
Read more >
MATCH function - Microsoft Support
The MATCH function searches for a specified item in a range of cells, and then returns the relative position of that item in...
Read more >
How to use INDEX and MATCH - Exceljet
INDEX and MATCH is the most popular tool in Excel for performing more advanced ... Let's say we want to write a formula...
Read more >
INDEX & MATCH for Flexible Lookups
It helps the INDEX function to locate the answer. The MATCH function was designed to return the position or address of the lookup...
Read more >
What is INDEX MATCH & Why Should You Use It? - GoSkills
We used the match type 0 to ensure that only an exact match will be returned. INDEX MATCH example 5 The MATCH function...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found