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 types unable to match on `Nothing`

See original GitHub issue

Apologies if this is expected behavior. I am trying to constrain the return type of Behavior Response to be Unit instead of Nothing for CounterMsg.Inc extends CounterMsg[Nothing] but it appears I can’t type match on Nothing?

The code works if I instead use the line // type ResponseOf[O] = O | Unit and comment the one with the match type. But it allows Unit type despite O isn’t necessarily Nothing

Compiler version

3.1.3

Minimized code

type ResponseOf[O] = O match
  case Nothing => Unit
  case _       => O

// type ResponseOf[O] = O | Unit

type Behavior[S, -I[_]] = [O] => ((S, I[O]) => (S, ResponseOf[O]))

enum CounterMsg[+Response]:
  case Inc
  case Get extends CounterMsg[Int]

val counterFsm: Behavior[Int, CounterMsg] =
  [O] =>
    (state: Int, msg: CounterMsg[O]) =>
      (msg match
        case CounterMsg.Inc => state + 1 -> ()
        case CounterMsg.Get => state -> state
      ): (Int, ResponseOf[O])

Scastie: https://scastie.scala-lang.org/KG1Q2sbVSUawd18xXk5kXQ

Output

Found:    (state : Int)
Required: Playground.ResponseOf[O]

where:    O is a type in method apply with bounds >: Int

Expectation

Compiles successfully

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
oderskycommented, Jul 7, 2022

I think as long as we don’t have a clear issue we should close this.

1reaction
prolativcommented, Jul 7, 2022

I think the compiler might be right to reject this code (although I’m not sure if the error messages could be more informative in such situations in general). If you define CounterMsg as covariant then Inc would be a subtype of both CounterMsg[Nothing] and CounterMsg[Int] so code like

counterFsm(1, CounterMsg.Inc: CounterMsg[Int])

should compile. But then in

[O] =>
    (state: Int, msg: CounterMsg[O]) =>
      (msg match
        case CounterMsg.Inc => state + 1 -> ()
        case CounterMsg.Get => state -> state
      ): (Int, ResponseOf[O])

O would get substituted with Int and while case CounterMsg.Inc pattern gets matched, the type of state + 1 -> () should be (Int, ResponseOf[O]), which should further expand to (Int, Int) but it’s actually (Int, Unit)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Match Types - Scala 3 - EPFL
A match type reduces to one of its right-hand sides, depending on the type of its scrutinee. ... Int Elem[List[Float]] =:= Float Elem[Nil.type]...
Read more >
Scala 3 Match Types and F-Bounded types: "Cannot prove"
In this Scastie, the compiler claims it can't be shown to match or be disjoint from UnitOfMeasure[t] , which is odd. – user....
Read more >
Match Types in Scala 3
Recursive Match Types. Since match types can be recursive, there's nothing preventing us from writing an infinite loop. Luckily, the Scala ...
Read more >
How to customize the error message in match type - Question
I made the following example of an ad-hoc record built on match types + opaque type over Map[String, Any] in scala 3: gist.github.com ......
Read more >
Big Bad Broad Match: The Anti-Hero of Keyword Match Types
The broad match type often gets written off as the villain in PPC. Here's why it can pay to take a chance on...
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