I am trying to define a recursive lambda expression in scala and struggling a bit with sintax, if think that this is just a syntax:
Here is what I have so far (not compilable):
type rec = (Int => Int, Int)
val f = (x : Int) => x + x
val y : rec = (f:Int => Int, x:Int) => if (x > 0) y( f, 1) else 1
Error I am getting:
ScalaFiddle.scala:14: error: ScalaFiddle.rec does not take parameters
val y : rec = (f:Int => Int, x:Int) => if (x > 0) y( f, 1) else 1
^
Original code sample I am trying to optimize (which works fine):
case class Rec[I, O](fn : (I => O, I) => O) extends (I => O) {
def apply(v : I) = fn(this, v)
}
val sum = Rec[Int, Int]((f, v) => if (v == 0) 0 else v + f(v - 1))
Any help would be appreciated.
Thanks
rec is a tuple of type Tuple2[Int => Int,Int].
in your statement val y : rec = (f:Int => Int, x:Int) => if (x > 0) y( f, 1) else 1, you are trying to call a apply function on the tuple y (y(f,1)). Since the tuple doesnt have a apply function defined you are getting the error rec does not take parameters
as per your sample code your type rec (Int => Int, Int) => Int.
so the code sample would be
type rec = (Int => Int, Int) => Int
val f = (x : Int) => x + x
val y : rec = (f:Int => Int, x:Int) => if (x > 0) y( f, 1) else 1
Check This link for this answer explanation
var sumIt:(Int => Int) = (x: Int) => {if(x<=1) 1 else sumIt(x-1)+x
Related
I'm learning closure in scala programming language.
For example:
val a = (x:Int, y:Int) => x + y;
a(1, 2)
will give me 3. the closure a works like a function (Int, Int):Int.
Is it possible to declare the return type for closure like this ?
val a = (x:Int, y:Int):Int => x + y;
a(1, 2)
Is it possible ?
This syntax is impossible (val a = (x:Int, y:Int):Int => x + y), but you can declare type for a:
val a: (Int, Int) => Int = (x, y) => x + y
Is there a convenient way to convert a function with type Int => Seq[Int] to Seq[Int => Int] in scala?
For example:
val f = (x: Int) => Seq(x * 2, x * 3)
I want to convert it to
val f = Seq((x: Int) => x * 2, (x: Int) => x * 3)
Generally, it is impossible.
For example, you have a function x => if (x < 0) Seq(x) else Seq(x * 2, x * 3). What is the size of the Seq that your hypothetical function will return?
As #ZhekaKozlov has pointed out, collections are going to be a problem because the type is the same no matter the size of the collection.
For tuples, on the other hand, the size is part of the type so you could do something like this.
val f1 = (x: Int) => (x * 2, x * 3) //f1: Int => (Int, Int)
val f2 = ((x:Int) => f1(x)._1, (y:Int) => f1(y)._2) //f2: (Int => Int, Int => Int)
Not exactly a "convenient" conversion, but doable.
I am trying to parallelize recursive calls of sudoku solver from 25 lines Sudoku solver in Scala. I've changed their Fold into reduce
def reduce(f: (Int, Int) => Int, accu: Int, l: Int, u: Int): Int = {
accu + (l until u).toArray.reduce(f(accu, _) + f(accu, _))
}
which if run sequentially works fine, but when I change it into
accu + (l until u).toArray.par.reduce(f(accu, _) + f(accu, _))
the recursion reaches the bottom much more often and generates false solutions. I thought, that it will execute the bottom level recursion and work it's way up, but doesn't seem to do so.
I've also tried futures
def parForFut2(f: (Int, Int) => Int, accu: Int, l: Int, u: Int): Int = {
var sum: Int = accu
val vals = l until u
vals.foreach(t => scala.actors.Futures.future(sum + f(accu, t)))
sum
}
which appears to have the same problem as the par.reduce. I would appreciate any comment. The whole code is here:
object SudokuSolver extends App {
// The board is represented by an array of string
val source = scala.io.Source.fromFile("./puzzle")
val lines = (source.getLines).toArray
var m: Array[Array[Char]] = for (
str <- lines;
line: Array[Char] = str.toArray
) yield line
source.close()
// For printing m
def print = {
Console.println("");
refArrayOps(m) map (carr => Console.println(new String(carr)))
}
// The test for validity of n on position x,y
def invalid(i: Int, x: Int, y: Int, n: Char): Boolean =
i < 9 && (m(y)(i) == n || m(i)(x) == n ||
m(y / 3 * 3 + i / 3)(x / 3 * 3 + i % 3) == n || invalid(i + 1, x, y, n))
// Looping over a half-closed range of consecutive Integers [l..u)
// is factored out Into a higher-order function
def parReduce(f: (Int, Int) => Int, accu: Int, l: Int, u: Int): Int = {
accu + (l until u).toArray.par.reduce(f(accu, _) + f(accu, _))
}
// The search function examines each position on the board in turn,
// trying the numbers 1..9 in each unfilled position
// The function is itself a higher-order fold, accumulating the value
// accu by applying the given function f to it whenever a solution m
// is found
def search(x: Int, y: Int, f: (Int) => Int, accu: Int): Int = Pair(x, y) match {
case Pair(9, y) => search(0, y + 1, f, accu) // next row
case Pair(0, 9) => f(accu) // found a solution - print it and continue
case Pair(x, y) => if (m(y)(x) != '0') search(x + 1, y, f, accu) else
parForFut1((accu: Int, n: Int) =>
if (invalid(0, x, y, (n + 48).asInstanceOf[Char])) accu else {
m(y)(x) = (n + 48).asInstanceOf[Char];
val newaccu = search(x + 1, y, f, accu);
m(y)(x) = '0';
newaccu
}, accu, 1, 10)
}
// The main part of the program uses the search function to accumulate
// the total number of solutions
Console.println("\n" + search(0, 0, i => { print; i + 1 }, 0) + " solution(s)")
}
As far as I can tell, recursion is inherently sequential (i.e. not parallelizable).
I'd reason it like this: recursion means (put simply) 'call myself'. A function call always happens within one and exactly one thread.
If you are telling the function to call itself, then you are staying in that thread - you're not dividing the work (i.e. making it parallel).
Recursion and parallelism are related though, but not at the function-call level. They are related in the sense that tasks can be recursively decomposed into smaller parts, that can be performed in parallel.
After Andreas comment I changed the m: Array[Array[Char]] into m: List[List[Char]] which prevents any unnecessary and unwanted changes to it. The final looping method is
def reduc(f: (Int, Int) => Int,
accu: Int, l: Int, u: Int, m1: List[List[Char]]):Int =
accu + (l until u).toArray.par.reduce(f(accu, _) + f(accu, _))
and I had to pass m as an argument to each used function, so every one of them had its own instance of it. The whole code:
object SudokuSolver extends App{
// The board is represented by an Array of strings (Arrays of Chars),
val source = scala.io.Source.fromFile("./puzzle")
val lines = source.getLines.toList
val m: List[List[Char]] = for (
str <- lines;
line: List[Char] = str.toList
) yield line
source.close()
// For prInting m
def printSud(m: List[List[Char]]) = {
Console.println("")
m map (println)
}
Console.println("\nINPUT:")
printSud(m)
def invalid(i:Int, x:Int, y:Int, n:Char,m1: List[List[Char]]): Boolean =
i < 9 && (m1(y)(i) == n || m1(i)(x) == n ||
m1(y / 3 * 3 + i / 3)(x / 3 * 3 + i % 3) == n ||
invalid(i + 1, x, y, n, m1))
def reduc(f: (Int, Int) => Int, accu: Int, l: Int, u: Int,
m1: List[List[Char]]): Int =
accu + (l until u).toArray.par.reduce(f(accu, _) + f(accu, _))
def search(x: Int, y: Int, accu: Int, m1: List[List[Char]]): Int =
Pair(x, y) match {
case Pair(9, y) => search(0, y + 1, accu, m1) // next row
case Pair(0, 9) => { printSud(m1); accu + 1 } // found a solution
case Pair(x, y) =>
if (m1(y)(x) != '0')
search(x + 1, y, accu, m1) // place is filled, we skip it.
else // box is not filled, we try all n in {1,...,9}
reduc((accu: Int, n: Int) => {
if (invalid(0, x, y, (n + 48).asInstanceOf[Char], m1))
accu
else { // n fits here
val line = List(m1(y).patch(x, Seq((n + 48).asInstanceOf[Char]), 1))
val m2 = m1.patch(y, line, 1)
val newaccu = search(x + 1, y, accu, m2);
val m3 = m1.patch(y, m1(y).patch(x, Seq(0), 1), 1)
newaccu
}
}, accu, 1, 10, m1)
}
Console.println("\n" + search(0, 0, 0, m) + " solution(s)")
}
I'm new to scala and confused why this code is giving me this error.
def div(m: Int, n: Int, i: Int): Int = {
(m: Int, n: Int) =>
if ((m - n) <= 0)
return i
else
div((m-n), n, (i+1))
}
Help appreciated.
It looks like you're returning a function rather than an Int like you're declaring.
Is this what you're trying to do:
def div(m: Int, n: Int, i: Int): Int = if ((m - n) <= 0) return i else div((m-n), n, (i+1))
(x: A) => y: B means an anonymous function of type A => B, so the expression you have between the braces is a function (Int, Int) => Int, and that's what gets returned.
You use a big number of superflous stuff, the return- keyword, parenthesis, and the whole (m: Int, n:Int) => - part.
def div (m: Int, n: Int, count: Int): Int =
if ((m - n) <= 0) count else div (m - n, n, count + 1)
If you like to use a match, you could do it this way:
def div (m: Int, n: Int, count: Int = 1): Int = (m - n) match {
case (diff: Int) if (diff <= 0) => count
case _ => div (m - n, n, count + 1) }
(note the default-argument of count = 1).
m,n,i are a little bit too much short-named variables for my taste. Beneath count, nominator, denominator would fit.
However, the implentation returns
(0 to 2).map (x => div (14+x, 5, 1))
res61: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 3, 4)
where I would expect (2, 3, 3) - you're rounding in the opposite direction.
if ((m - n) < 0) i-1 else ...
would fix that - changing the comparator, and returning i-1 (count-1).
However, this is not testet for values including 0 and negative values.
I'd like to convert a single value into a collection of multiple "characteristics", without using a mutable data structure to collect the values. I'd like something like this fantasy construct which uses pattern matching, but does not stop after first match:
scala> 2 multimatch {
case i if i > 0 => "Positive"
case i if i < 0 => "Negative"
case i if (i % 2 == 0) => "Even"
//yadda yadda
}
res0: Seq[java.lang.String] = List(Positive, Even)
Using the pimp pattern, partial functions and repeated parameters, this is how close I can get:
class MultiMatcher[A](a: A) {
def multiMatch[B](pfs: PartialFunction[A, B]*): Seq[B] = {
pfs.map(_.lift(a)).collect{ case Some(v) => v }
}
}
implicit def toMultiMatcher[A](a:A): MultiMatcher[A] = new MultiMatcher(a)
2 multiMatch (
{ case i if i > 0 => "Positive" },
{ case i if i < 0 => "Negative" },
{ case i if i % 2 == 0 => "Even" }
)
// returns Seq[java.lang.String] = ArrayBuffer(Positive, Even)
First you define your characteristics as functions from Int to Option[String]
val pos = (i:Int) => if (i > 0) Some("Positive") else None
val neg = (i:Int) => if (i < 0) Some("Negative") else None
val even = (i:Int) => if (i % 2 == 0) Some("Even") else None
Then you make a list of characteristics.
val characteristics = pos::neg::even::Nil
And then you use flatmap to get a list of those characteristics that apply to a certain object.
scala> characteristics.flatMap(f=>f(2))
res6: List[java.lang.String] = List(Positive, Even)
First, define a multimatch function as follows:
scala> def multimatch[A,B]( value : A,ps: ( A => Boolean, B)*) =
| for ( p <- ps
| if (p._1(value))) yield p._2
multimatch: [A,B](value: A,ps: ((A) => Boolean, B)*)Seq[B]
Then, here we go:
scala> multimatch(2,
| ( ((x :Int) => x > 0) -> "POSITIVE"),
| ( ((x :Int) => x < 0) -> "NEGATIVE"),
| ( ((x :Int) => x % 2 == 0) -> "EVEN")
| )
res4: Seq[java.lang.String] = ArrayBuffer(POSITIVE, EVEN)
Or, less cluttered:
scala> multimatch(2,
| ( (x :Int) => x > 0 , "POSITIVE"),
| ( (x :Int) => x < 0, "NEGATIVE"),
| ( (x :Int) => x % 2 == 0, "EVEN")
| )
res5: Seq[java.lang.String] = ArrayBuffer(POSITIVE, EVEN)