Best way to write a generic method that checks whether a number is 0 in scala - scala

I know this is very trivial to do with a simple case check, but it seems it should be possible to write a method that does something like the following, that is generalizes to all numeric types:
def checkNonZero(t: Long, field: String): List[String] = {
if (t == 0) println("was zero") else println("wasn't zero")
}
What's the best way to do this?

This can be done with the Number type.
def checkNonZero(n: Number) = n != 0
Or you can use the Numeric typeclass.
def checkNonZero[T : Numeric](n: T) = {
val num = implicitly[Numeric[T]]
!num.equiv(n, num.zero)
}
EDIT
Actually, you can just write it like this:
def checkNonZero[T : Numeric](n: T) = n != 0
Unless you define new custom instances of Numeric of course.

An alternative way to Jasper-M's second solution goes as follows:
def isNotZero[A](n: A)(implicit num: Numeric[A]) = !num.equiv(n, num.zero)
This saves the line val num = implicitly[Numeric[A]], while still allowing you to work with num if you so desire.
Despite this method actually taking 2 parameters, because the second one's implicit, you can use it like you would any other non-curried single-parameter method:
isNotZero(3) // true
isNotZero(0.1) // true
isNotZero(0) // false
isNotZero(0.0) // false

Related

Scala comparing type:Ordering

I have a sorting function like this:
def sort[A:Ordering](vals: Array[A]):Array[A] = {
for (i <- 1 until vals.length) {
val temp = vals(i)
var j = i
while (j > 0 && temp < vals(j-1) ){
vals(j) = vals(j-1)
j -= 1
}
vals(j) = temp;
}
vals
}
And its supposed to get an array of type A(which is either Int or String, but the code doesn't know that) as a parameter and sort it and then return it.
Now eclipse tells me that:
"value < is not a member of type parameter A"
at line 5. I don´t understand why can't it compare those values, I've tried A:Comparable, A:Ordered and A:every-word-that-could-possibly-work. Nothing works.
Any help is appreciated!
Thanks!
[A:Ordering] on a function sort means that there should exist such implicit value (to be completely honest it may not be implicit, but in this case you'll have to pass it by manually), that has type Ordering[A] at the point of sort call, and this implicit value will be added in separate argument list of the function.
This is how typeclasses supported in Scala.
This won't magically add < to A, as there is no type bound on A and compiller can know no more that A is a subtype of Any.
Anyway, to use ordering in body of your sort you can obtain it using:
implicitly[Ordering[A]]
... and then use it. This works because, again implicit value of type Ordering[A] were added behind the scenes in extra argument list of sort.
Here is a code snippet that should give you an idea on how to use it in your code:
scala> def lt[T : Ordering](a: T, b: T) = { implicitly[Ordering[T]].lt(a, b) }
lt: [T](a: T, b: T)(implicit evidence$1: Ordering[T])Boolean
scala> lt(1, 1)
res9: Boolean = false
scala> lt(1, 2)
res10: Boolean = true

Scala, Exercise with recursive function

Trying to solve the exercises in the book "Scala for the Impatient", I have a little problem. (Below are my solutions)
1: Write a for loop for computing the product of the Unicode codes of all letters in a string. For example, the product of the characters in "Hello" is 825152896
var p = 1; val S = "Hello"
for (i <- S) p*= i
println(p)
2: Solve the preceding exercise without writing a loop. (Hint: look at the String0ps Scaladoc.)
val St="Hello".map(_.toInt).product ; println(St)
3: Write a function product(s : String) that computes the product, as described in the preceding exercises.
def product(s: String)={
val S=s; println(S.map(_.toInt).product)
}
product("Hello")
Make the function of the preceding exercise a recursive function.
??? I do not know how to do it
I hope that someone can help me.
Best regards,
Francesco
Using well-known recursive functions and modifying them to comply with a different problem may prove quite a helpful approach.
Consider as a start-up pattern the factorial recursive function,
def factorial(n: Int): Int =
if (n <= 1) 1 else n * factorial (n-1)
Consider now the factorial recursive function where the input is assumed to be a list of integers from 1 to n, and so note the way the input list is reduced to the base case,
def factorial(xs: List[Int]): Int =
if (xs.isEmpty) 1 else xs.head * factorial (xs.tail)
This transformation is now closer to a solution for the original problem on string input.
Ok...finally my code works:
def prodRec(s: String): Int = {
if (s.toList.isEmpty) 1
else {
s.toList.head * prodRec(s.tail)
}
}
println(prodRec("Hello"))
I hope that this code snippet might help someone else...
best regards
francesco
Here is another way of writing the recursive solution to the product:
def getProduct(s: String):Int = {
def accumulate(acc:Int,ch:Array[Char]):Int = {
ch.headOption match {
case None => acc
case Some(x) => accumulate(acc*x.toInt,ch.tail)
}
}
accumulate(1,s.toArray)
}
Maybe I solved with:
def prodRec(s: String): Int = {
var s2 =s.toList
if (s2.isEmpty) 1
else {
s2.head * prodRec (s.tail)
}
}
My variant of tail recursive function. No vars used, which is a plus.
def product(s: String): Unit = {
#tailrec
def help(z: Long, array: Array[Char]): Long = {
if (array.isEmpty) z else help(z * array.head.toInt, array.tail)
}
print(help(1L, s.toCharArray))
}
def product (s:String): Long ={
if (s.length==1) s(0) else s.head * s.product (s.tail)
}

Scala operator overloading with multiple parameters

In short: I try to write something like A <N B for a DSL in Scala, for an integer N and A,B of Type T. Is there a nice possibility to do so?
Longer: I try to write a DSL for TGrep2 in Scala. I'm currently interested to write
A <N B B is the Nth child of A (the rst child is <1).
in a nice way and as close as possible to the original definition in Scala. Is there a way to overload the < Operator that it can take a N and a B as a argument.
What I tried: I tried two different possibilities which did not make me very happy:
scala> val N = 10
N: Int = 10
scala> case class T(n:String) {def <(i:Int,j:T) = println("huray!")}
defined class T
scala> T("foo").<(N,T("bar"))
huray!
and
scala> case class T(n:String) {def <(i:Int) = new {def apply(j:T) = println("huray!")}}
defined class T
scala> (T("foo")<N)(T("bar"))
warning: there were 1 feature warnings; re-run with -feature for details
huray!
Id suggest you use something like nth instead of the < symbol which makes the semantics clear. A nth N is B would make a lot of sense to me at least. It would translate to something like
case class T (label:String){
def is(j:T) = {
label equals j.label
}
}
case class J(i:List[T]){
def nth(index:Int) :T = {
i(index)
}
}
You can easily do:
val t = T("Mice")
val t1 = T("Rats")
val j = J(List(t1,t))
j nth 1 is t //res = true
The problem is that apply doesn't work as a postfix operator, so you can't write it without the parantheses, you could write this:
case class T(n: String) {
def <(in: (Int, T)) = {
in match {
case (i, t) =>
println(s"${t.n} is the ${i} child of ${n}")
}
}
}
implicit class Param(lower: Int) {
def apply(t: T) = (lower, t)
}
but then,
T("foo") < 10 T("bar")
would still fail, but you could work it out with:
T("foo") < 10 (T("bar"))
there isn't a good way of doing what you want without adding parenthesis somewhere.
I think that you might want to go for a combinational parser instead if you really want to stick with this syntax. Or as #korefn proposed, you break the compatibility and do it with new operators.

How to check to see if a string is a decimal number in Scala

I'm still fairly new to Scala, and I'm discovering new and interesting ways for doing things on an almost daily basis, but they're not always sensible, and sometimes already exist within the language as a construct and I just don't know about them. So, with that preamble, I'm checking to see if a given string is comprised entirely of digits, so I'm doing:
def isAllDigits(x: String) = x.map(Character.isDigit(_)).reduce(_&&_)
is this sensible or just needlessly silly? It there a better way? Is it better just to call x.toInt and catch the exception, or is that less idiomatic? Is there a performance benefit/drawback to either?
Try this:
def isAllDigits(x: String) = x forall Character.isDigit
forall takes a function (in this case Character.isDigit) that takes an argument that is of the type of the elements of the collection and returns a Boolean; it returns true if the function returns true for all elements in the collection, and false otherwise.
Do you want to know if the string is an integer? Then .toInt it and catch the exception. Do you instead want to know if the string is all digits? Then ask one of:
s.forall(_.isDigit)
s matches """\d+"""
You also may consider something like this:
import scala.util.control.Exception.allCatch
def isLongNumber(s: String): Boolean = (allCatch opt s.toLong).isDefined
// or
def isDoubleNumber(s: String): Boolean = (allCatch opt s.toDouble).isDefined
You could simply use a regex for this.
val onlyDigitsRegex = "^\\d+$".r
def isAllDigits(x: String) = x match {
case onlyDigitsRegex() => true
case _ => false
}
Or simply
def isAllDigits(x: String) = x.matches("^\\d+$")
And to improve this a little bit, you can use the pimp my library pattern to make it a method on your string:
implicit def AllDigits(x: String) = new { def isAllDigits = x.matches("^\\d+$") }
"12345".isAllDigits // => true
"12345foobar".isAllDigits // => false
Starting Scala 2.13 we can use String::toDoubleOption, to determine whether a String is a decimal number or not:
"324.56".toDoubleOption.isDefined // true
"4.06e3".toDoubleOption.isDefined // true
"9w01.1".toDoubleOption.isDefined // false
Similar option to determine if a String is a simple Int:
"324".toIntOption.isDefined // true
"à32".toIntOption.isDefined // false
"024".toIntOption.isDefined // true
import scala.util.Try
object NumCruncher {
def isShort(aString: String): Boolean = Try(aString.toLong).isSuccess
def isInt(aString: String): Boolean = Try(aString.toInt).isSuccess
def isLong(aString: String): Boolean = Try(aString.toLong).isSuccess
def isDouble(aString: String): Boolean = Try(aString.toDouble).isSuccess
def isFloat(aString: String): Boolean = Try(aString.toFloat).isSuccess
/**
*
* #param x the string to check
* #return true if the parameter passed is a Java primitive number
*/
def isNumber(x: String): Boolean = {
List(isShort(x), isInt(x), isLong(x), isDouble(x), isFloat(x))
.foldLeft(false)(_ || _)
}
}
Try might not performance-wise be the optimal choice, but otherwise it's neat:
scala> import scala.util.Try
scala> Try{ "123x".toInt }
res4: scala.util.Try[Int] = Failure(java.lang.NumberFormatException: For input string: "123x")
scala> Try{ "123x".toInt }.isSuccess
res5: Boolean = false
#Jesper's answer is spot on.
Do NOT do what I'm suggesting below (explanation follows)
Since you are checking if a given string is numeric (title states you want a decimal), the assumption is that you intend to make a conversion if the forall guard passes.
A simple implicit in scope will save a whopping 9 key strokes ;-)
implicit def str2Double(x: String) = x.toDouble
Why this is dangerous
def takesDouble(x: Double) = x
The compiler will now allow takesDouble("runtime fail") since the implicit tries to convert whatever string you use to Double, with zero guarantee of success, yikes.
implicit conversions then seem better suited to situations where an acceptable default value is supplied on conversion failure (which is not always the case; therefore implicit with caution)
Here is one more:
import scala.util.Try
val doubleConverter: (String => Try[Double]) = (s: String) => Try{ s.map(c => if ((Character.isDigit(c) == true) || (c == '.')) Some(c) else None).flatten.mkString.toDouble }
val d1: Try[Double] = doubleConverter("+ 1234.0%")
val d2: Try[Double] = doubleConverter("+ 1234..0%")
Based on brilliant Jexter's solution, in this piece of code I take care of the NullPointerException using Option:
def isValidPositiveNumber(baseString: Option[String]): Boolean = baseString match {
case Some(code) => !code.isEmpty && (code forall Character.isDigit)
case None => false
}

How to use scala.util.Sorting.quickSort() with arbitrary types?

I need to sort an array of pairs by second element. How do I pass comparator for my pairs to the quickSort function?
I'm using the following ugly approach now:
type AccResult = (AccUnit, Long) // pair
class Comparator(a:AccResult) extends Ordered[AccResult] {
def compare(that:AccResult) = lessCompare(a, that)
def lessCompare(a:AccResult, that:AccResult) = if (a._2 == that._2) 0 else if (a._2 < that._2) -1 else 1
}
scala.util.Sorting.quickSort(data)(d => new Comparator(d))
Why is quickSort designed to have an ordered view instead of usual comparator argument?
Scala 2.7 solutions are preferred.
I tend to prefer the non-implicit arguments unless its being used in more than a few places.
type Pair = (String,Int)
val items : Array[Pair] = Array(("one",1),("three",3),("two",2))
quickSort(items)(new Ordering[Pair] {
def compare(x: Pair, y: Pair) = {
x._2 compare y._2
}
})
Edit: After learning about view bounds in another question, I think that this approach might be better:
val items : Array[(String,Int)] = Array(("one",1),("three",3),("two",2))
class OrderTupleBySecond[X,Y <% Comparable[Y]] extends Ordering[(X,Y)] {
def compare(x: (X,Y), y: (X,Y)) = {
x._2 compareTo y._2
}
}
util.Sorting.quickSort(items)(new OrderTupleBySecond[String,Int])
In this way, OrderTupleBySecond could be used for any Tuple2 type where the type of the 2nd member of the tuple has a view in scope which would convert it to a Comparable.
Ok, I'm not sure exactly what you are unhappy about what you are currently doing, but perhaps all you are looking for is this?
implicit def toComparator(a: AccResult) = new Comparator(a)
scala.util.Sorting.quickSort(data)
If, on the other hand, the problem is that the tuple is Ordered and you want a different ordering, well, that's why it changed on Scala 2.8.
* EDIT *
Ouch! Sorry, I only now realize you said you preferred Scala 2.7 solutions. I have editted this answer soon to put the solution for 2.7 above. What follows is a 2.8 solution.
Scala 2.8 expects an Ordering, not an Ordered, which is a context bound, not a view bound. You'd write your code in 2.8 like this:
type AccResult = (AccUnit, Long) // pair
implicit object AccResultOrdering extends Ordering[AccResult] {
def compare(x: AccResult, y: AccResult) = if (x._2 == y._2) 0 else if (x._2 < y._2) -1 else 1
}
Or maybe just:
type AccResult = (AccUnit, Long) // pair
implicit val AccResultOrdering = Ordering by ((_: AccResult)._2)
And use it like:
scala.util.Sorting.quickSort(data)
On the other hand, the usual way to do sort in Scala 2.8 is just to call one of the sorting methods on it, such as:
data.sortBy((_: AccResult)._2)
Have your type extend Ordered, like so:
case class Thing(number : Integer, name: String) extends Ordered[Thing] {
def compare(that: Thing) = name.compare(that.name)
}
And then pass it to sort, like so:
val array = Array(Thing(4, "Doll"), Thing(2, "Monkey"), Thing(7, "Green"))
scala.util.Sorting.quickSort(array)
Printing the array will give you:
array.foreach{ e => print(e) }
>> Thing(4,Doll) Thing(7,Green) Thing(2,Monkey)