How to take into account all cases of listing on the right side of the template

Exhaustive pattern matching is fine, but it only works on the left side of the case ( =>

) statement .

I am curious if there is a way to check that the output of a function (or expression) can be associated with this enum. The goal would be for the compiler to tell me when I forgot to take an item out of the enumeration.

In my example, I am using the following enum containing three elements:

object MyEnum { 
    sealed trait t 
    case object E1 extends t
    case object E2 extends t
    case object E3 extends t
}

      

And here is a template expression expression that would generate a compile-time warning (as we already know):

def foo( e : MyEnum.t ) : Boolean =
    e match {
        case MyEnum.E1 => true
        case MyEnum.E2 => false
        case MyEnum.E3 => true   // if we leave this line out, we get a warning
    }

      

Scala will complain if we get out of the pattern matching expression by MyEnum.E3

citing non-exhaustive pattern matching. This is very helpful, but I'm wondering if the opposite is possible.

Can we count all the cases MyEnum.t

on the right side =>

?

Here's an example that highlights the following:

def bar( s : String ) : Option[MyEnum.t] = 
    s match {
        case "a" => Some(MyEnum.E1)
        case "b" => Some(MyEnum.E2)
        case "c" => Some(MyEnum.E3)  // if we leave this out, no warning
        case _ => None
    }

      

In this example, if we omit the c line MyEnum.E3

, then the compiler will just continue as if nothing had happened. The statement I would like to make is this:

forall MyEnum.t (aliased as e) there exists Some(e) | None

      

I understand that this can easily be covered by a test at runtime, but I'm curious if there is a way to test this statically.

Thank.

+3


source to share


2 answers


I'm going to push my luck and argue that this is impossible (let it be kept secret from Odersky). If the Scala compiler was able to detect such situations, I think it will be even slower than it already is;)

The only way I could see is to define foo in a similar way to how you did it and define the bar by iterating over foo to make a reverse map, but that doesn't really matter to me and may not work in your particular case.



I think your case is a very good example of when unit tests are useful, so why not just write one?

0


source


No, this is not possible, because it is equivalent to the halting problem, which was proved unsolvable in 1936.



0


source







All Articles