HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Matching BigInts in Scala

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scalabigintsmatching

Problem

I'm currently in the process of learning scala, and I'm looking for some best practices/proper idioms for the use of pattern matching with BigInts. I'm writing some algorithmic code (for Project Euler) as a way to learn the language.

The problem I am running into is what is the best idiomatic way to match a BigInt, since there's a type conversion problem if I try to write case 1 => and BigInt isn't a case class. Is there a canonical way to do this, or should I just give up and use if statements?

The following is one possible pattern:

def pollardRho(n: BigInt): BigInt = {
  val one = BigInt(1)

  n match {
    case `one` => n
    //additional cases here
  }
}


This one just feels wrong: A hack to get around the fact that I can't match it directly, especially with the backticks in there to keep scala from trying to assign the resulting value to one or when I have to do it for more than a single value or in a single case.

Another possibility:

def pollardRho(n: BigInt): BigInt = {

  n match {
    case _ if n == 1 => n
    //additional cases here
  }
}


This sort of pattern appeals to the Erlang programmer in me, but I have some concerns:

  • Given the warnings I've read not to treat Scala like any other language, I am not sure that my instinct here is not an anti-pattern (or at least considered less readable) in the scala world.



  • It feels like there might be cleaner way to use a custom PartialFunction instead of n match if what I am fundamentally going to do is just a series of tests around n. I am not sure, however, exactly what that would look like (most of the examples of PartialFunctions I've seen don't look quite like this application).



My question is, out of the array of possibilities in scala, which one is the best/most readable/most idiomatic?

Solution

Write your own extractor:

object Big {
  def unapply(n:BigInt) = Some(n.toInt)
}

//usage
def f(b:BigInt) = b match {
   case Big(0) => "none"
   case Big(1) => "one"
   case _ => "many"
}


Obviously, this isn't the fastest solution, but I think, it's quite idiomatic...

Code Snippets

object Big {
  def unapply(n:BigInt) = Some(n.toInt)
}

//usage
def f(b:BigInt) = b match {
   case Big(0) => "none"
   case Big(1) => "one"
   case _ => "many"
}

Context

StackExchange Code Review Q#14561, answer score: 4

Revisions (0)

No revisions yet.