I'm trying to write a function myfoo which, taken an Int and a list of ints, verifies if the int element is in the list or not. It should return "true" if the int is in the list, false otherwise.
I've written this function, but when I compile it it returns this error:
error: type mismatch;
found : Unit
required: Boolean
breakable { for (i <-l) {
^
one error found*
This is my program:
import scala.util.control.Breaks._
object findEl extends App{
def myfoo (x:Int,l:List[Int]):Boolean={
breakable { for (i <-l) {
i match {
case a if (a==x) => true
case _ => false
break
}
}
}
}
println(myfoo(1,List(1,2,3,4))) //should print "true"
}
How can I solve it? :)
This is how breakable is implemented
def breakable(op: => Unit) {
try {
op
} catch {
case ex: BreakControl =>
if (ex ne breakException) throw ex
}
}
Breakable returns Unit finally. So thats why compiler is complaining.
Here is one way to fix this. Notice I am using var
import scala.util.control.Breaks._
object findEl extends App {
def myfoo(x: Int, l: List[Int]): Boolean = {
var res: Boolean = false
breakable {
for (i <- l) {
i match {
case a if a == x => res = true
break
case _ => ()
}
}
}
res
}
println(myfoo(1, List(1, 2, 3, 4))) //should print "true"
}
Functional way (better way) of implementing the same
def myFoo(num: Int, list: List[Int]): Boolean = list match {
case Nil => false
case `num` :: xs => true
case _ => myFoo(num, list.tail)
}
Below code is same but does not use back ticks
def myFoo(num: Int, list: List[Int]): Boolean = list match {
case Nil => false
case x :: xs if x == num => true
case _ => myFoo(num, list.tail)
}
Scala REPL
scala> def myFoo(num: Int, list: List[Int]): Boolean = list match {
| case Nil => false
| case `num` :: xs => true
| case _ => myFoo(num, list.tail)
| }
myFoo: (num: Int, list: List[Int])Boolean
scala> myFoo(1, List(2, 1, 2))
res0: Boolean = true
Using breakable is not functional practice
Halting the execution of the program using an exception is not functional. Functional programming advocates communicating through interpretation of types. Internally breakable halts the control flow by throwing exception.
Above second way is the way to solve the problem functionally.
you can use this trick instead
def function myFoo(x:Int, xList:List[Int]) = xList.contains(x)
println(myFoo(1, List(1,2,3,4,5,6)))
Related
Hello im trying to use case match with a high order function. if function return true do things same for false. Thank you.
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f match
{
case true => do something
case false => do somethingelse
}
}
Looks like a good place to apply "andThen" for partial function:
Here is possibly what you need:
def funk(ls: List[Int], f: Int => Boolean): List[Int] = {
val z = f.andThen(r => r match {
case true => List(1, 2) // ..something
case false => List(3, 4) // somethingElse
})
// function application
z(5)
}
Just dig a bit around PartialFunction's:
http://www.scala-lang.org/api/current/scala/PartialFunction.html
you have to execute the function and pass the return value to the match case as
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f(some integer value) match
{
case true => return a list of integers
case false => return a list of integers
}
}
for example
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f(ls(0)) match
{
case true => List(1,2)
case false => List(4,3)
}
}
Say I want to do a simple conversion of strings to ints thus:
List("1", "3", "55", "x", "7") => List(1, 3, 55, 7)
One way to do this would be the following recursive call:
def recurse1(strs: List[String]): List[Int] = strs match {
case h :: t =>
try {
h.toInt :: recurse1(t)
}
catch {
case _ : java.lang.NumberFormatException =>
recurse1(t)
}
case _ =>
List()
}
However this cannot be compiled as tail recursive due to line 4 in the code. So to get around this I can redefine the function as follows:
def recurse2(strs: List[String], accum: List[Int] = List()): List[Int] = strs match {
case h :: t =>
try {
recurse2(t, h.toInt :: accum)
}
catch {
case _ : java.lang.NumberFormatException =>
recurse2(t, accum)
}
case _ =>
accum.reverse
}
So my question is this. Is there an idiom I can use in scala that will allow me to do this tail recursively but without having to pass a variable to accumulate the values?
Maybe your recurse method is just for illustration but for completeness I'll add to #pamu's answer how to use standard functions:
def foo(ss: List[String]): List[Int] =
ss.map(s => Try(s.toInt).toOption)
.filter(_.isDefined)
.map(_.get)
or
def foo(ss: List[String]): List[Int] =
ss.map(s => Try(s.toInt))
.collect { case Success(n) => n }
Usually, I see programmers write a helper function which takes many arguments (internally) which is specific to method/algorithm you are using. They write a minimal interface function around the ugly internal function which is tail recursive and takes only inputs required and hides the internal mechanism.
def reverse(input: List[Sting]): List[Int] = {
def helper(strs: List[String], accum: List[Int] = List()): List[Int] =
strs match {
case h :: t =>
try {
helper(t, h.toInt :: accum)
}
catch {
case _ : java.lang.NumberFormatException =>
helper(t, accum)
}
case _ =>
accum.reverse
}
helper(input, List.empty[Sting])
}
I'm writing a function and having a strange issue. I'm using pattern matching, and then an internal function which uses a slightly changed but almost identical pattern and it isn't compiling:
def isTriangular(n: Int): Boolean = {
n match {
case n if n < 1 => false
case _ => triangularMaths(n, 1)
}
def triangularMaths(j:Int, counter: Int): Boolean = (j, counter) match {
case _ if j-counter == 0 => true
case _ if j-counter < 0 => false
case _ => triangularMaths(j-counter, counter+1)
}
}
The fix for this is I simply make them two seperate methods, and they work as long as triangularMaths isn't nested. However, since triangularMaths is specific to triangular only, I'd like it to be nested. However, when I do this, my compiler complains, telling me I am returning Unit, rather than the expected Boolean . This doesn't quite make sense, as once the original case brackets is resolved, returning true or false, it should go to the end of the method, and complete, correct? What's the fix?
This happens because your method is the last declaration in scope, which makes the compiler emit the Unit value as the return type. Decompiled code looks like this:
def main(args: Array[String]): Unit = {
def isTriangular(n: Int): Boolean = {
n match {
case (n # _) if n.<(1) => false
case _ => triangularMaths(n, 1)
};
def triangularMaths(j: Int, counter: Int): Boolean = scala.Tuple2.apply[Int, Int](j, counter) match {
case _ if j.-(counter).==(0) => true
case _ if j.-(counter).<(0) => false
case _ => triangularMaths(j.-(counter), counter.+(1))
};
()
};
First define triangularMaths, and then invoke it:
def isTriangular(n: Int): Boolean = {
def triangularMaths(j: Int, counter: Int): Boolean = (j, counter) match {
case _ if j - counter == 0 => true
case _ if j - counter < 0 => false
case _ => triangularMaths(j - counter, counter + 1)
}
n match {
case n if n < 1 => false
case _ => triangularMaths(n, 1)
}
}
Another possibility would be to assign the pattern match to a value, and then return that value as the last expression of the method. But, that would make the compiler complain about forward reference, which you could fix by making it a lazy val instead. I would stick the the re-ordering approach.
Lately, I frequently end up writing code like that:
def doSomethingWithLotsOfConditions(arg1, arg2, arg3...) {
arg1.get(arg2) match {
case Some(value1) =>
arg3.get(value1) match {
case Some(value2) =>
arg4.get(arg5, value2) match {
case Some(value3) =>
finallyDoSomethingInside(value3)
case None =>
log("Some excuse for being unable to work with arg4/arg5...")
}
case None =>
log("Some excuse for being unable to work with arg3")
}
case None =>
log("Some excuse for being unable to work with arg1/arg2")
}
}
A somewhat related question seems to heavily advocate for such usage of nested match, although, from my point of view, it hardly seems readable, concise or easy-to-understand: (1) it kind of splits the check itself and its aftermath, (2) it makes code uncontrollably nested without any real rationale for nesting. In these particular cases, I would be glad to structure the code something in lines of:
def doSomethingWithLotsOfConditions(arg1, arg2, arg3...) {
// Step 1
val value1Opt = arg1.get(arg2)
if (value1Opt.isEmpty) {
log("Some excuse for being unable to work with arg1/arg2")
return
}
val value1 = value1Opt.get
// Step 2
val value2Opt = arg3.get(value1)
if (value2Opt.isEmpty) {
log("Some excuse for being unable to work with arg3")
return
}
val value2 = value2Opt.get
// Step 3
val value3Opt = arg4.get(arg5, value2)
if (value3Opt.isEmpty) {
log("Some excuse for being unable to work with arg4/arg5...")
return
}
val value3 = value3Opt.get
// All checked - we're free to act!
finallyDoSomethingInside(value3)
}
However, that pattern (i.e. valueXOpt = (...).get => check isEmpty => value = valueXOpt.get) looks really ugly and is also definitely too verbose. Hell, even Java version would look more concise:
Value1Type value1 = arg1.get(arg2);
if (value1 != null) {
log("Some excuse for being unable to work with arg1/arg2");
return;
}
Is there a better, cleaner alternative, i.e. for getting the value and specifying alternative short escape route (that log a line + return), without going nested with matches?
How about this?
object Options{
implicit class OptionLog[T](val option:Option[T]) extends AnyVal{
def ifNone(body: =>Unit):Option[T] = option.orElse {
body
option
}
}
}
import Options._
def something(arg1:Option[Int], arg2:Option[String], arg3:Option[Long], arg4:Option[Any]){
for{
val1 <- arg1 ifNone(println("arg1 was none"))
val2 <- arg2 ifNone(println("arg2 was none"))
val3 <- arg3 ifNone(println("arg3 was none"))
}{
println(s"doing something with $val1, $val2, $val3")
}
}
Then ...
scala> something(Some(3), Some("hello"), None, Some("blah"))
arg3 was none
scala> something(Some(3), Some("hello"), Some(10l), Some("blah"))
doing something with 3, hello, 10
Maybe you mean, for a condition x:
scala> def f(x: Option[Int]): Int = x orElse { println("nope"); return -1 } map (_ + 1) getOrElse -2
f: (x: Option[Int])Int
scala> f(Some(5))
res3: Int = 6
scala> f(None)
nope
res4: Int = -1
or even
scala> def f(x: Option[Int], y: Option[Int]): Int = (for (i <- x orElse { println("nope"); return -1 }; j <- y orElse { println("gah!"); return -2 }) yield i + j) getOrElse -3
f: (x: Option[Int], y: Option[Int])Int
scala> f(Some(5), None)
gah!
res5: Int = -2
Sorry if I'm oversimplifying.
Don't you want to use the map method?
def doSomethingWithLotsOfConditions(arg1, arg2, arg3...) =
arg1.get(arg2).map(value1 =>
arg3.get(value1).map(value2 =>
arg4.get(arg5, value2).map(value3 =>
finallyDoSomethingInside(value3)).
getOrElse(log("Some excuse for being unable to work with arg4/arg5"))).
getOrElse(log("Some excuse for being unable to work with arg3"))).
getOrElse(log("Some excuse for being unable to work with arg1/arg2"))
It is still nested but it's at least more elegant-looking than your pattern matching above.
Or you can implement your own Functor for this one:
trait Foo[+A] {
def fmap[B](f: A => B): Foo[B]
}
case class Bar[A](value: A) {
def fmap[B](f: A => B): Foo[B] = Bar(f(value))
}
case object Error[Nothing](message: String) {
def fmap[B](f: Nothing => B) = Error(message)
}
def doSomethingWithLotsOfConditions(arg1, arg2, arg3, arg4, arg5) =
arg1.get(arg2).fmap(value1 =>
arg3.get(value1).fmap(value2 =>
arg4.get(arg5, value2).fmap(value3 =>
finallyDoSomethingInside))
def processResult = doSomethingWithLotsOfConditions(...) match {
case Bar(a) => doSomething
case Error(message) => log(message)
}
This code assumes that arg.get returns a Foo.
I have a method that is recursive. Is there a way in scala to break out based on the size of the buffer (as shown below)? A case for breaking out when elementList.size > 5 for example?
val elementList = ListBuffer.empty[Book]
#tailrec
def getBooks(elements: List[Element]) {
elements match {
case Nil => info("Reached end of elements list.")
case element :: rest if element.getElementType == ElementType.BOOK => {
elementList.append(element.getBook)
getLooks(rest)
}
case _ => getBooks(elements.tail)
}
}
I guess the most simple way would be to just wrap an if statement around your match statement like this:
val elementList = ListBuffer.empty[Book]
#tailrec
def getBooks(elements: List[Element]) {
if (elementList.size <= 5){
elements match {
case Nil => info("Reached end of elements list.")
case element :: rest if element.getElementType == ElementType.BOOK => {
elementList.append(element.getBook)
getLooks(rest)
}
case _ => getBooks(elements.tail)
}
}
}
Genereally speaking you could try to pass down the number of remaining elements in the recursion.
For example:
def get(list: List[Int], max: Int): List[Int] = {
#tailrec
def get(list: List[Int], acc: List[Int], remaining: Int): List[Int] = {
list match {
case h :: tail if remaining > 0 =>
get(tail, h :: acc, remaining - 1)
case _ =>
acc
}
}
// Requires reverse() !
get(list, Nil, max).reverse
As for the accumulator: you could use a buffer instead, to prevent the reverse() at the end.