5
scala> (1,5) == BigInt(12) /% 7
res3: Boolean = true

scala> BigInt(12) /% 7 match {
 | case (1,5) => true
 | }

<console>:9: error: type mismatch;
found   : Int(1)
required: scala.math.BigInt
          case (1,5) => true
                ^

Can someone perhaps explain me how to pattern match here?

3 Answers3

9

match is more specific than equality; you can't just be equal, you must also have the same type.

In this case, BigInt is not a case class and does not have an unapply method in its companion object, so you can't match on it directly. The best you could do is

  BigInt(12) /% 7 match {
    case (a: BigInt,b: BigInt) if (a==1 && b==5) => true
    case _ => false
  }

or some variant thereof (e.g. case ab if (ab == (1,5)) =>).

Alternatively, you could create an object with an unapply method of appropriate type:

object IntBig { def unapply(b: BigInt) = Option(b.toInt) }

scala> BigInt(12) /% 7 match { case (IntBig(1), IntBig(5)) => true; case _ => false }
res1: Boolean = true
Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • Binding to variables and a guard is what I did. I just thaught it could perhaps be done a little better. Thank you. –  Nov 11 '12 at 19:11
1

1 and 5 are Int types. The pattern match is expecting a scala.math.BigInt. So, give it that by declaring a couple of vals for one and five.

scala> val OneBig = BigInt(1)
oneBig: scala.math.BigInt = 1

scala> val FiveBig = BigInt(5)
fiveBig: scala.math.BigInt = 5

scala> BigInt(12) /% 7 match {
     | case (OneBig, FiveBig) => true
     | }
res0: Boolean = true
Brian
  • 20,195
  • 6
  • 34
  • 55
  • 3
    This doesn't work! `oneBig` and `fiveBig` in the pattern are new variables unrelated to the ones defined before. This can be changed by naming them with a capital letter (`OneBig` and `FiveBig`) or by surrounding the names in backticks. – Alexey Romanov Nov 11 '12 at 18:59
  • Thanks. Forgot about that. For those interested see http://stackoverflow.com/questions/4479474/scala-pattern-matching-with-lowercase-variable-name or page 317 of the stairway book. – Brian Nov 11 '12 at 19:02
0

The problem is that 1 and 5 returned by /% are BigInts and so don't match literal Ints even though equals method (called by ==) returns true. This works but is a bit inelegant:

scala> BigInt(12) /% 7 match { case (x, y) if x == 1 && y == 5 => true }
res3: Boolean = true
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487