Scala: where to put the #unchecked annotation in a foreach - scala

I have the following:
samples.sliding(2).foreach{case List(a, b)=> printf("%x %x\n", a.value, b.value)}
I know that the single 'case' will match all the possible values but I get a 'match is not exhaustive' warning. The Scala book explains where to put the #unchecked annotation on a normal fully-specified match expression, but not for the form above. How do I annotate the above to stop the compiler from complaining?

#unchecked is only defined for the selector in a match operation, not for arbitrary functions. So you could
foreach{ x => (x: #unchecked) => x match { case List(a,b) => ... } }
but that is rather a mouthful.
Alternatively, you could create a method that unsafely converts a partial function to a complete one (which actually just casts to the function superclass of PartialFunction):
def checkless[A,B](pf: PartialFunction[A,B]): A => B = pf: A => B
and then you can
samples.sliding(2).foreach(checkless{
case List(a,b) => printf("%x %x\n", a.value, b.value)
})
and you don't have any warnings because it was expecting a partial function.

No idea about #unchecked, but why not just call x.head and x.tail.head or x(0) and x(1)?

Why don't you add an dummy case, if you're sure it will never happen?
samples.sliding (2).foreach {
case List (a, b) => printf ("%x %x\n", a.value, b.value)
case _ => sys.error ("impossible")
}

Related

Understand Scala match for case classes with two members

I've been working with Scala for a while and it still troubles me a lot. I don't know why they made it so complex. I am trying to understand matching case classes when there are only two members for this case class
def main(args: Array[String]): Unit = {
case class X(a: String, i: Int)
def doSome(x: X): Unit = {
x match {
case "x" X 1 => print("ahhh") // <---- HERE !
case X(_, _) => println("")
}
}
doSome(X("x", 1))
case class Y(a: String, i: Int, j: Int)
def doAnother(y:Y): Unit = {
y match {
case "y" X 1 => print("ahhh") // how to make similar syntax when there are more than one syntax ?
case Y(_, _,_) => println("") // this is understandable
}
}
doAnother(Y("y", 1,2))
}
How can the syntax "x" X 1 match X("x",1) and if "x" X 1 can match match X("x",1) then what matches Y("y",1,2), obviously "y" Y 1 Y 2 doesn't work?
What is so special about the first argument if we can match on "y" Y (1,2)?
At least in case of List it feels more natural to me, for example consider
List(42, 11) match {
case head :: tail =>
case Nil =>
}
as opposed to
List(42, 11) match {
case ::(head, tail) =>
case Nil =>
}
where head :: tail communicates directly the shape of the List.
As a side note, infix notation can sometimes communicate intent more clearly, for example, consider syntax of generalised constraints
implicitly[List[Int] <:< Iterable[Int]] // infix type notation seems more natural
implicitly[<:<[List[Int], Iterable[Int]]]
You don't have to use a language feature just because it is there.
In this case I can see no reason not to use the standard class matching version:
x match {
case X("x", 1) => print("ahhh")
case _ => println("")
}
}
y match {
case Y("y", 1, _) => print("ahhh")
case _ => println("")
}
Ok, so the thing I was looking for is called "Infix Types". From Scala for Impatient, 2nd edition
An infix type is a type with two type parameters, written in “infix”
syntax, with the type name between the type parameters. For example,
you can write String Map Int instead of Map[String, Int] The
infix notation is common in mathematics. For example, A × B = { (a, b)
| a Œ A, b Œ B } is the set of pairs with components of types A and B.
In Scala, this type is written as (A, B). If you prefer the
mathematical notation, you can define type ×[A, B] = (A, B) Then you
can write String × Int instead of (String, Int). All infix type
operators have the same precedence. As with regular operators, they
are left-associative unless their names end in :. For example,
String × Int × Int means ((String, Int), Int). This type is similar
to, but not the same, as (String, Int, Int), which could not be
written in infix form in Scala.
To answer your query on What is so special about the first argument if we can match on "y" Y (1,2)?: this is because of how your case class gets decomposed via its unapply method.
The preferred way of matching against a case class is how you've done in the second statement of both your methods.
However, for Y, the preferred way to match would be case Y("y", 1, 2) as mentioned in Tim's comment.
For X, a few ways you can use power of pattern matching are (similarly for Y):
case X("x", 1) => ???
case X(a, 1) => ???
case X(_, 1) => ???
case X("x", _) => ???
case x#X("x", _) =>
case X(a, b) if b > 5 => ???
The following, however, is a very bad style as it compromises readability and hence maintainability of the code
case "x" X 1 => print("ahhh")
As Mario mentioned, the way you're using pattern matching is more suited for lists instead of case classes, as it makes your code consistent with the way a list is structured (head cons tail), and thus enhances readability.
You can go through following articles for a more deeper understanding on how to exploit the power of scala's pattern matching:
https://www.artima.com/pins1ed/case-classes-and-pattern-matching.html
https://docs.scala-lang.org/tour/pattern-matching.html
https://docs.scala-lang.org/overviews/scala-book/match-expressions.html

Scala: Type missing parameter type for expanded function The argument types of an anonymous function must be fully known. (SLS 8.5) [duplicate]

I have a function literal
{case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }
Which results in an error message
missing parameter type for expanded function The argument types of an anonymous function
must be fully known. (SLS 8.5) Expected type was:
? => Option[(Typer.this.EqualityConstraintSet, Typer.this.TypeRelationSet)]
I looked in SLS 8.5, but didn't find an explanation.
If I expand the function myself to
{(qt : QualifiedType) =>
qt match {case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }}
the error goes away.
(a) Why is this an error?
(b) What can I do to fix it?
I tried the obvious fix, which was to add : QualifiedType between the pattern and the =>, but this is a syntax error.
One thing I noticed is that the context makes a difference. If I use the function literal as an argument to a function declared as expecting a QualifiedType => B, there is no error. But if I use it as an argument to a function expecting an A => B, there is an error. I expect that what is going on here is that, as the pattern could conceivably be applied to an object whose type is a supertype of QualifiedType, the compiler is not willing to assign the obvious type without assurance that the function won't be applied to anything that isn't a QualifiedType. Really what I'd like is to be able to write {QualifiedType( preds, ty) => ...}
and have it mean the same thing as Haskell's \QualifiedType(preds,ty) -> ....
{ case X(x) => ... } is a partial function, but the compiler still doesn't know what your input type is, except that it's a supertype of X. Normally this isn't a problem because if you're writing an anonymous function, the type is known from the context. But here is how you can provide the type:
case class Foo(x: Int)
// via annotation
val f: Foo => Int = { case Foo(x) => x }
// use pattern matching
val f = (_: Foo) match { case Foo(x) => x }
// or more normally, write as a method
def f(a: Foo) = a match { case Foo(x) => x }
def f(a: Foo) = a.x
As you've probably noticed, using function literals / pattern matching here is pretty pointless. It seems in your case you just need a regular method:
def whatever(qt: QualifiedType) = {
t.ty = qt.ty
Some((emptyEqualityConstraintSet, qt.preds))
}
although you should refactor to remove that mutable state.
Here's the SLS quote, for the rest of us:
The expected type of such an expression must in part be defined. It
must be either scala.Functionk[S1, . . . , Sk, R] for some k > 0, or
scala.PartialFunction[S1, R], where the argument type(s) S1, . . . ,
Sk must be fully determined, but the result type R may be
undetermined.
Otherwise, you answered your question.
Here is why I wanted to use a function literal and didn't like having to repeat the type twice. I was trying to build my own control construct to factor out all the option matching code. If there is too much overhead, then the control construct doesn't help any. Here is what I wanted to do
//This is the control construct definition
def switch[A,B]( x : Option[A], noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
//And this is an example of using it.
def foobar( qt : Option[QualifiedType] ) =
switch( qt, {reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
The switch control construct compiles fine, but the usage caused an error because the SLS says that where I have an A, I should have a "definite type". That's because this kind of function literal (the kind with "case") is intended for partial functions where the argument could be legitimately any thing at all. I could argue my function literal with an int and that would not be a type error, but merely a matter of all the patterns failing. So the compiler needs some "top down" information to know what type I intend for the parameter of the "expanded function literal", i.e. what to put for X in the following
{(x : X) => x match {case Some(QualifiedType(preds, ty)) =>
Some((emptyEqualityConstraintSet,preds)) } }
I wonder why the compiler could't use the type of switch to see that I don't intend a partial function and then unify A with QualifiedType. But it doesn't.
Anyway it doesn't compile. But replacing A with Any eliminates the error. The following code actually compiles. What I lose is some type checking.
//This is the control construct definition
def switch[A,B]( x : Option[A], noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
//And this is an example of using it.
def foobar( qt : Option[QualifiedType] ) =
switch( qt, {reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
I'd be interested to know (a) if the above definition of switch can be improved, and (b) if there is already a library function that does what I want.
Added after Luigi's Comment
Here is the final code. Yes, I think it is a fold (catamorphism).
def switch[A,B]( x : Option[A])(noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
def foobar( qt : Option[QualifiedType] ) : Option[(EqualityConstraintSet, TypeRelationSet)] =
switch( qt )({reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
Thanks to Luigi.

How to suppress "match is not exhaustive!" warning in Scala

How can I suppress the "match is not exhaustive!" warning in the following Scala code?
val l = "1" :: "2" :: Nil
l.sliding(2).foreach{case List(a,b) => }
The only solution that I found so far is to surround the pattern matching with an additional match statement:
l.sliding(2).foreach{x => (x: #unchecked) match {case List(a,b) => }}
However this makes the code unnecessarily complex and pretty unreadable. So there must be a shorter and more readable alternative. Does someone know one?
Edit
I forgot to mention that my list l has at least 2 elements in my program. That's why I can safely suppress the warning.
Here are several options:
You can match against Seq instead of List, since Seq doesn't have the exhaustiveness checking (this will fail, like your original, on one element lists):
l.sliding(2).foreach{case Seq(a, b) => ... }
You can use a for comprehension, which will silently discard anything that doesn't match (so it will do nothing on one element lists):
for (List(a, b) <- l.sliding(2)) { ... }
You can use collect, which will also silently discard anything that doesn't match (and where you'll get an iterator back, which you'll have to iterate through if you need to):
l.sliding(2).collect{case List(a,b) => }.toList
Making it complete with ; case _ => ??? is pretty short. ??? just throws an exception. You can define your own if you're using 2.9 or before (it's new in 2.10).
It really is pretty short compared to what you need for a match annotation:
(: #unchecked)
; case _ => ???
^ One more character!
It doesn't throw a MatchError, but does that really matter?
Since your sliding(2) can possibly return one last list with only one element in it, you should also test it:
l sliding(2) foreach {
case a::b::Nil => println("two elements: " + a + b)
case l => println("one last element" + l.head)
}
implicit class RichAny[A](private val a: A) extends AnyVal {
#inline
def match_ignoring_nonexhaustive[B](f: PartialFunction[A,B]): B = f(a)
}
With this you could do the following, which actually only interprets the case match as PartialFunction:
l.sliding(2).foreach{ _ match_ignoring_nonexhaustive {case List(a,b) => }}

The argument types of an anonymous function must be fully known. (SLS 8.5)

I have a function literal
{case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }
Which results in an error message
missing parameter type for expanded function The argument types of an anonymous function
must be fully known. (SLS 8.5) Expected type was:
? => Option[(Typer.this.EqualityConstraintSet, Typer.this.TypeRelationSet)]
I looked in SLS 8.5, but didn't find an explanation.
If I expand the function myself to
{(qt : QualifiedType) =>
qt match {case QualifiedType(preds, ty) =>
t.ty = ty ;
Some((emptyEqualityConstraintSet,preds)) }}
the error goes away.
(a) Why is this an error?
(b) What can I do to fix it?
I tried the obvious fix, which was to add : QualifiedType between the pattern and the =>, but this is a syntax error.
One thing I noticed is that the context makes a difference. If I use the function literal as an argument to a function declared as expecting a QualifiedType => B, there is no error. But if I use it as an argument to a function expecting an A => B, there is an error. I expect that what is going on here is that, as the pattern could conceivably be applied to an object whose type is a supertype of QualifiedType, the compiler is not willing to assign the obvious type without assurance that the function won't be applied to anything that isn't a QualifiedType. Really what I'd like is to be able to write {QualifiedType( preds, ty) => ...}
and have it mean the same thing as Haskell's \QualifiedType(preds,ty) -> ....
{ case X(x) => ... } is a partial function, but the compiler still doesn't know what your input type is, except that it's a supertype of X. Normally this isn't a problem because if you're writing an anonymous function, the type is known from the context. But here is how you can provide the type:
case class Foo(x: Int)
// via annotation
val f: Foo => Int = { case Foo(x) => x }
// use pattern matching
val f = (_: Foo) match { case Foo(x) => x }
// or more normally, write as a method
def f(a: Foo) = a match { case Foo(x) => x }
def f(a: Foo) = a.x
As you've probably noticed, using function literals / pattern matching here is pretty pointless. It seems in your case you just need a regular method:
def whatever(qt: QualifiedType) = {
t.ty = qt.ty
Some((emptyEqualityConstraintSet, qt.preds))
}
although you should refactor to remove that mutable state.
Here's the SLS quote, for the rest of us:
The expected type of such an expression must in part be defined. It
must be either scala.Functionk[S1, . . . , Sk, R] for some k > 0, or
scala.PartialFunction[S1, R], where the argument type(s) S1, . . . ,
Sk must be fully determined, but the result type R may be
undetermined.
Otherwise, you answered your question.
Here is why I wanted to use a function literal and didn't like having to repeat the type twice. I was trying to build my own control construct to factor out all the option matching code. If there is too much overhead, then the control construct doesn't help any. Here is what I wanted to do
//This is the control construct definition
def switch[A,B]( x : Option[A], noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
//And this is an example of using it.
def foobar( qt : Option[QualifiedType] ) =
switch( qt, {reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
The switch control construct compiles fine, but the usage caused an error because the SLS says that where I have an A, I should have a "definite type". That's because this kind of function literal (the kind with "case") is intended for partial functions where the argument could be legitimately any thing at all. I could argue my function literal with an int and that would not be a type error, but merely a matter of all the patterns failing. So the compiler needs some "top down" information to know what type I intend for the parameter of the "expanded function literal", i.e. what to put for X in the following
{(x : X) => x match {case Some(QualifiedType(preds, ty)) =>
Some((emptyEqualityConstraintSet,preds)) } }
I wonder why the compiler could't use the type of switch to see that I don't intend a partial function and then unify A with QualifiedType. But it doesn't.
Anyway it doesn't compile. But replacing A with Any eliminates the error. The following code actually compiles. What I lose is some type checking.
//This is the control construct definition
def switch[A,B]( x : Option[A], noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
//And this is an example of using it.
def foobar( qt : Option[QualifiedType] ) =
switch( qt, {reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
I'd be interested to know (a) if the above definition of switch can be improved, and (b) if there is already a library function that does what I want.
Added after Luigi's Comment
Here is the final code. Yes, I think it is a fold (catamorphism).
def switch[A,B]( x : Option[A])(noneFun : =>B, someFun : A=>B) = x match {
case None => noneFun
case Some(y) => someFun(y) }
def foobar( qt : Option[QualifiedType] ) : Option[(EqualityConstraintSet, TypeRelationSet)] =
switch( qt )({reportError("SNAFU");None},
{case QualifiedType(preds, ty) =>
Some((emptyEqualityConstraintSet,preds)) } )
Thanks to Luigi.

How is a match word omitted in Scala?

In Scala, you can do
list.filter { item =>
item match {
case Some(foo) => foo.bar > 0
}
}
But you can also do the quicker way by omitting match:
list.filter {
case Some(foo) => foo.bar > 0
}
How is this supported in Scala? Is this new in 2.9? I have been looking for it, and I can figure out what makes this possible. Is it just part of the Scala compiler?
Edit: parts of this answer are wrong; please refer to huynhjl's answer.
If you omit the match, you signal the compiler that you are defining a partial function. A partial function is a function that is not defined for every input value. For instance, your filter function is only defined for values of type Some[A] (for your custom type A).
PartialFunctions throw a MatchError when you try to apply them where they are not defined. Therefore, you should make sure, when you pass a PartialFunction where a regular Function is defined, that your partial function will never be called with an unhanded argument. Such a mechanism is very useful e.g. for unpacking tuples in a collection:
val tupleSeq: Seq[(Int, Int)] = // ...
val sums = tupleSeq.map { case (i1, i2) => i1 + i2 }
APIs which ask for a partial function, like the collect filter-like operation on collections, usually call isDefinedAt before applying the partial function. There, it is safe (and often wanted) to have a partial function that is not defined for every input value.
So you see that although the syntax is close to that of a match, it is actually quite a different thing we're dealing with.
The language specification addresses that in section 8.5. The relevant portions:
An anonymous function can be defined by a sequence of cases
{ case p1 => b1 ... case pn => bn }
If the expected type is scala.Functionk[S1, ..., Sk, R] , the expression is taken to
be equivalent to the anonymous function:
(x1 : S1, ..., xk : Sk) => (x1, ..., xk) match {
case p1 => b1 ... case pn => bn
}
If the expected type is scala.PartialFunction[S, R], the expression is taken to
be equivalent to the following instance creation expression:
new scala.PartialFunction[S, T ] {
def apply(x: S): T = x match {
case p1 => b1 ... case pn => bn
}
def isDefinedAt(x: S): Boolean = {
case p1 => true ... case pn => true
case _ => false
}
}
So typing the expression as PartialFunction or a Function influences how the expression is compiled.
Also trait PartialFunction [-A, +B] extends (A) ⇒ B so a partial function PartialFunction[A,B] is also a Function[A,B].
-- Revised post --
Hmm, I'm not sure I see a difference, Scala 2.9.1.RC3,
val f: PartialFunction[Int, Int] = { case 2 => 3 }
f.isDefinedAt(1) // evaluates to false
f.isDefinedAt(2) // evaluates to true
f(1) // match error
val g: PartialFunction[Int, Int] = x => x match { case 2 => 3 }
g.isDefinedAt(1) // evaluates to false
g.isDefinedAt(2) // evaluates to true
g(1) // match error
It seems f and g behave exactly the same as PartialFunctions.
Here's another example demonstrating the equivalence:
Seq(1, "a").collect(x => x match { case s: String => s }) // evaluates to Seq(a)
Even more interesting:
// this compiles
val g: PartialFunction[Int, Int] = (x: Int) => {x match { case 2 => 3 }}
// this fails; found Function[Int, Int], required PartialFunction[Int, Int]
val g: PartialFunction[Int, Int] = (x: Int) => {(); x match { case 2 => 3 }}
So there's some special casing at the compiler level to convert between x => x match {...} and just {...}.
Update. After reading the language spec, this seems like a bug to me. I filed SI-4940 in the bug tracker.