Apply a list of functions in specific order - scala

I have some functions that represent choices, each choice having a distinct desirability. Consider
f1 : Seq[A] => Seq[A]
f2 : Seq[A] => Seq[A]
f3 : Seq[A] => Seq[A]
where f1 is more desirable than f2, and f3 is least desirable. I wrote this scala code to generate the results of making 2 consecutive choices, ordered from most desirable to least
def applyTwice[A](initial: Seq[A],
f1: Seq[A] => Seq[A],
f2: Seq[A] => Seq[A],
f3: Seq[A] => Seq[A]): Seq[A] = {
lazy val f1s = f1(initial).toStream
lazy val f2s = f2(initial).toStream
lazy val f3s = f3(initial).toStream
f1(f1s) ++
f2(f1s) ++ f1(f2s) ++
f2(f2s) ++
f1(f3s) ++ f3(f1s) ++
f2(f3s) ++ f3(f2s) ++
f3(f3s)
}
In general, a series of function applications is ranked by the worst function in the series. If the worst is a tie, compare the 2nd worst, and so on. For example, f4(f1(a)) would be worse than f3(f3(a)) because f4 is worse than f3. Note that it is a tie between f3(f2(a)) and f2(f3(a)).
I probably could generalize this to a variable number of functions, and (with more difficulty) a variable number of applications, but this seems like a classic problem that I just don't know the name of yet. Is this already built into some language/library? Is there a better way?

I don't think that it's a well-known thing, but it's pretty easy to generalise:
import scala.math.max
case class Fun[A](cost : Int, fun : Seq[A] => Seq[A])
def applyN[A](funs : Seq[Fun[A]], n : Int, initial : Seq[A]) =
(Seq((0, initial)) /: (1 to n)) {
case (acc, _) => for {
f <- funs
(cost, old) <- acc
} yield (max(cost, f.cost), f.fun(old))
}
scala> val funs = Seq(Fun[Int](2, _.map(_*2)), Fun[Int](3, _.map(_*3)))
funs: Seq[Fun[Int]] = List(Fun(2,), Fun(3,))
scala> applyN(funs, 2, Seq(1,2,3,4))
res0: Seq[(Int, Seq[Int])] = List((2,List(4, 8, 12, 16)), (3,List(6, 12, 18, 24)), (3,List(6, 12, 18, 24)), (3,List(9, 18, 27, 36)))
Edit: I notice I've used a simplified cost function here, which just looks at the max, but you could easily collect the list of costs and apply whatever decision you wanted to them instead.

Related

Efficient and/or idiomatic way to turn Seq[Either[String, Int]] to (Seq[String], Seq[Int])

Slightly simplifying, my problem comes from a list of strings input that I want to parse with a function parse returning Either[String,Int].
Then list.map(parse) returns a list of Eithers. The next step in the program is to format an error message summing up all the errors or passing on the list of parsed integers.
Lets call the solution I'm looking for partitionEithers.
Calling
partitionEithers(List(Left("foo"), Right(1), Left("bar")))
Would give
(List("foo", "bar"),List(1))
Finding something like this in the standard library would be best. Failing that some kind of clean, idiomatic and efficient solution would be best. Also some kind of efficient utility function I could just paste into my projects would be ok.
I was very confused between these 3 earlier questions. As far as I can tell, neither of those questions matches my case, but some answers there seem to contain valid answers to this question.
Scala collections offer a partition function:
val eithers: List[Either[String, Int]] = List(Left("foo"), Right(1), Left("bar"))
eithers.partition(_.isLeft) match {
case (leftList, rightList) =>
(leftList.map(_.left.get), rightList.map(_.right.get))
}
=> res0: (List[String], List[Int]) = (List(foo, bar),List(1))
UPDATE
If you want to wrap it in a (maybe even somewhat type safer) generic function:
def partitionEither[Left : ClassTag, Right : ClassTag](in: List[Either[Left, Right]]): (List[Left], List[Right]) =
in.partition(_.isLeft) match {
case (leftList, rightList) =>
(leftList.collect { case Left(l: Left) => l }, rightList.collect { case Right(r: Right) => r })
}
You could use separate from MonadPlus (scalaz) or MonadCombine (cats) :
import scala.util.{Either, Left, Right}
import scalaz.std.list._
import scalaz.std.either._
import scalaz.syntax.monadPlus._
val l: List[Either[String, Int]] = List(Right(1), Left("error"), Right(2))
l.separate
// (List[String], List[Int]) = (List(error),List(1, 2))
I don't really get the amount of contortions of the other answers. So here is a one liner:
scala> val es:List[Either[Int,String]] =
List(Left(1),Left(2),Right("A"),Right("B"),Left(3),Right("C"))
es: List[Either[Int,String]] = List(Left(1), Left(2), Right(A), Right(B), Left(3), Right(C))
scala> es.foldRight( (List[Int](), List[String]()) ) {
case ( e, (ls, rs) ) => e.fold( l => ( l :: ls, rs), r => ( ls, r :: rs ) )
}
res5: (List[Int], List[String]) = (List(1, 2, 3),List(A, B, C))
Here is an imperative implementation mimicking the style of Scala collection internals.
I wonder if there should something like this in there, since at least I run into this from time to time.
import collection._
import generic._
def partitionEithers[L, R, E, I, CL, CR]
(lrs: I)
(implicit evI: I <:< GenTraversableOnce[E],
evE: E <:< Either[L, R],
cbfl: CanBuildFrom[I, L, CL],
cbfr: CanBuildFrom[I, R, CR])
: (CL, CR) = {
val ls = cbfl()
val rs = cbfr()
ls.sizeHint(lrs.size)
rs.sizeHint(lrs.size)
lrs.foreach { e => evE(e) match {
case Left(l) => ls += l
case Right(r) => rs += r
} }
(ls.result(), rs.result())
}
partitionEithers(List(Left("foo"), Right(1), Left("bar"))) == (List("foo", "bar"), List(1))
partitionEithers(Set(Left("foo"), Right(1), Left("bar"), Right(1))) == (Set("foo", "bar"), Set(1))
You can use foldLeft.
def f(s: Seq[Either[String, Int]]): (Seq[String], Seq[Int]) = {
s.foldRight((Seq[String](), Seq[Int]())) { case (c, r) =>
c match {
case Left(le) => (le +: r._1, r._2)
case Right(ri) => (r._1 , ri +: r._2)
}
}
}
val eithers: List[Either[String, Int]] = List(Left("foo"), Right(1), Left("bar"))
scala> f(eithers)
res0: (Seq[String], Seq[Int]) = (List(foo, bar),List(1))

Sequence with Streams in Scala

Suppose there is a sequence a[i] = f(a[i-1], a[i-2], ... a[i-k]). How would you code it using streams in Scala?
It will be possible to generalize it for any k, using an array for a and another k parameter, and having, f.i., the function with a rest... parameter.
def next(a1:Any, ..., ak:Any, f: (Any, ..., Any) => Any):Stream[Any] {
val n = f(a1, ..., ak)
Stream.cons(n, next(a2, ..., n, f))
}
val myStream = next(init1, ..., initk)
in order to have the 1000th do next.drop(1000)
An Update to show how this could be done with varargs. Beware that there is no arity check for the passed function:
object Test extends App {
def next(a:Seq[Long], f: (Long*) => Long): Stream[Long] = {
val v = f(a: _*)
Stream.cons(v, next(a.tail ++ Array(v), f))
}
def init(firsts:Seq[Long], rest:Seq[Long], f: (Long*) => Long):Stream[Long] = {
rest match {
case Nil => next(firsts, f)
case x :: xs => Stream.cons(x,init(firsts, xs, f))
}
}
def sum(a:Long*):Long = {
a.sum
}
val myStream = init(Seq[Long](1,1,1), Seq[Long](1,1,1), sum)
myStream.take(12).foreach(println)
}
Is this OK?
(a[i] = f(a[i-k], a[i-k+1], ... a[i-1]) instead of a[i] = f(a[i-1], a[i-2], ... a[i-k]), since I prefer to this way)
/**
Generating a Stream[T] by the given first k items and a function map k items to the next one.
*/
def getStream[T](f : T => Any,a : T*): Stream[T] = {
def invoke[T](fun: T => Any, es: T*): T = {
if(es.size == 1) fun.asInstanceOf[T=>T].apply(es.head)
else invoke(fun(es.head).asInstanceOf[T => Any],es.tail :_*)
}
Stream.iterate(a){ es => es.tail :+ invoke(f,es: _*)}.map{ _.head }
}
For example, the following code to generate Fibonacci sequence.
scala> val fn = (x: Int, y: Int) => x+y
fn: (Int, Int) => Int = <function2>
scala> val fib = getStream(fn.curried,1,1)
fib: Stream[Int] = Stream(1, ?)
scala> fib.take(10).toList
res0: List[Int] = List(1, 1, 2, 3, 5, 8, 13, 21, 34, 55)
The following code can generate a sequence {an} where a1 = 1, a2 = 2, a3 = 3, a(n+3) = a(n) + 2a(n+1) + 3a(n+2).
scala> val gn = (x: Int, y: Int, z: Int) => x + 2*y + 3*z
gn: (Int, Int, Int) => Int = <function3>
scala> val seq = getStream(gn.curried,1,2,3)
seq: Stream[Int] = Stream(1, ?)
scala> seq.take(10).toList
res1: List[Int] = List(1, 2, 3, 14, 50, 181, 657, 2383, 8644, 31355)
The short answer, that you are probably looking for, is a pattern to define your Stream once you have fixed a chosen k for the arity of f (i.e. you have a fixed type for f). The following pattern gives you a Stream which n-th element is the term a[n] of your sequence:
def recStreamK [A](f : A ⇒ A ⇒ ... A) (x1:A) ... (xk:A):Stream[A] =
x1 #:: recStreamK (f) (x2)(x3) ... (xk) (f(x1)(x2) ... (xk))
(credit : it is very close to the answer of andy petrella, except that the initial elements are set up correctly, and consequently the rank in the Stream matches that in the sequence)
If you want to generalize over k, this is possible in a type-safe manner (with arity checking) in Scala, using prioritized overlapping implicits. The code (˜80 lines) is available as a gist here. I'm afraid I got a little carried away, and explained it as an detailed & overlong blog post there.
Unfortunately, we cannot generalize over number and be type safe at the same time. So we’ll have to do it all manually:
def seq2[T, U](initials: Tuple2[T, T]) = new {
def apply(fun: Function2[T, T, T]): Stream[T] = {
initials._1 #::
initials._2 #::
(apply(fun) zip apply(fun).tail).map {
case (a, b) => fun(a, b)
}
}
}
And we get def fibonacci = seq2((1, 1))(_ + _).
def seq3[T, U](initials: Tuple3[T, T, T]) = new {
def apply(fun: Function3[T, T, T, T]): Stream[T] = {
initials._1 #::
initials._2 #::
initials._3 #::
(apply(fun) zip apply(fun).tail zip apply(fun).tail.tail).map {
case ((a, b), c) => fun(a, b, c)
}
}
}
def tribonacci = seq3((1, 1, 1))(_ + _ + _)
… and up to 22.
I hope the pattern is getting clear somehow. (We could of course improve and exchange the initials tuple with separate arguments. This saves us a pair of parentheses later when we use it.) If some day in the future, the Scala macro language arrives, this hopefully will be easier to define.

Find a function applied value in Scala

I have a problem that I've been trying to find the best solution to using the existing Scala collections library, but I can't seem to come up with something.
Given a set of functions, I need to find the first function result for some input that satisfies a predicate. Here's a simple implementation:
def findResult[A, B](t: Traversable[Function1[A, B]], value: A, p: B => Boolean): Option[B] = {
var result: Option[B] = None
breakable {
for (e <- t) {
val r = e(value)
if (p(r)) { result = Some(r); break }
}
}
result
}
// test
val f1 = (s: String) => if (s == "a") "aa" else null
val f2 = (s: String) => if (s == "b") "bb" else null
val l = List(f1, f2)
findResult(l, "b", (v: Any) => v != null) must equal(Some("bb"))
Is there a better way to do this using the Collections API?
Edit: One restriction I'd like to put in place is that each function should only be applied once, since while my example is trivial, my actual usage for this is not. This restriction is what led me to the implementation above.
I was going to just comment on tenshi's answer, but then I decided to expand it into an alternate approach. Note that if you use map on a strict Traversable, then the entire list will be mapped before any finding occurs. That means you will end up performing a little extra work.
You could instead just use a find:
def findResult[A, B](t: Traversable[Function1[A, B]], value: A, p: B => Boolean) =
t find (fn => p(fn(value)))
This will instead return the function that satisfies the predicate p for value. If you instead need the result, you need only apply the function to the value again (assuming the function is referentially transparent). This, of course, will therefore perform a little extra work, but is likely to be slightly less extra work than tenshi's technique. Note that the technique you came up with yourself performs no extra work.
[update] If you really don't want to perform any extra work, then you should use a collection view. I had to look this up, but I think I've got a handle on it. Now, stealing tenshi's code outright and adding .view, here's some copypasta from my interactive session:
def f1(x: Int): Int = { println("f1"); x }
f1: (x: Int)Int
def f2(x: Int): Int = { println("f2"); x+1 }
f2: (x: Int)Int
def f3(x: Int): Int = { println("f3"); x+2 }
f3: (x: Int)Int
val fs = List(f1 _, f2 _, f3 _)
fs: List[(Int) => Int] = List(, , )
(fs.view map (f => f(1))) find (_ == 2)
f1
f2
res8: Option[Int] = Some(2)
As you can see, f1 and f2 executed, but not f3. This is because once the result of f2(1) was found to be == 2, the find function was able to stop. That's part of the magic of views: lazy mapping. In fact, the map and find operations are fused together thanks to views! Or so I'm told.
def findResult[A, B](t: Traversable[Function1[A, B]], value: A, p: B => Boolean) =
t.view map (f => f(value)) find p
def even(x: Int) = x % 2 == 0
findResult(fs, 1, even)
f1
f2
res13: Option[Int] = Some(2)
So there you have it. One gem I found in the documentation I linked above was this:
[As of Scala 2.8] All collections except streams and views are strict. The only way to go from a strict to a lazy collection is via the view method. The only way to go back is via force.
You can use view:
def findResult[A, B](t: Traversable[Function1[A, B]], value: A, p: B => Boolean) = {
t.view.map(_(value)).find(p(_))
}
Combination of map and find should work:
def findResult[A, B](t: Traversable[Function1[A, B]], value: A, p: B => Boolean) =
t map (fn => fn(value)) find p

Scala: filtering a collection of Options

Say I have a function that checks whether some operation is applicable to an instance of A and, if so, returns an instance of B or None:
def checker[A,B]( a: A ) : Option[B] = ...
Now I want to form a new collection that contains all valid instances of B, dropping the None values. The following code seems to do the job, but there is certainly a better way:
val as = List[A]( a1, a2, a3, ... )
val bs =
as
.map( (a) => checker(a) ) // List[A] => List[Option[B]]
.filter( _.isDefined ) // List[Option[B]] => List[Option[B]]
.map( _.get ) // List[Option[B]] => List[B]
This should do it:
val bs = as.flatMap(checker)
The answer above is correct, but if you can rewrite checker, I suggest you use PartialFunction and collect. PartialFunction is a function of type A=>B that is not necessary defined for all values of A. Here is a simple example:
scala> List(1, 2, 3, 4, "5") collect {case x : Int => x + 42}
res1: List[Int] = List(43, 44, 45, 46)
collect takes an instance of PartialFunction as argument and applies it to all elements of the collection. In our case the function is defined only for Ints and "5" is filtered. So, collect is a combination of map and filter, which is exactly your case.

What's a good and functional way to swap collection elements in Scala?

In a project of mine one common use case keeps coming up. At some point I've got a sorted collection of some kind (List, Seq, etc... doesn't matter) and one element of this collection. What I want to do is to swap the given element with it's following element (if this element exists) or at some times with the preceding element.
I'm well aware of the ways to achieve this using procedural programming techniques. My question is what would be a good way to solve the problem by means of functional programming (in Scala)?
Thank you all for your answers. I accepted the one I myself did understand the most. As I'm not a functional programmer (yet) it's kind of hard for me to decide which answer was truly the best. They are all pretty good in my opinion.
The following is the functional version of swap with the next element in a list, you just construct a new list with elements swapped.
def swapWithNext[T](l: List[T], e : T) : List[T] = l match {
case Nil => Nil
case `e`::next::tl => next::e::tl
case hd::tl => hd::swapWithNext(tl, e)
}
A zipper is a pure functional data structure with a pointer into that structure. Put another way, it's an element with a context in some structure.
For example, the Scalaz library provides a Zipper class which models a list with a particular element of the list in focus.
You can get a zipper for a list, focused on the first element.
import scalaz._
import Scalaz._
val z: Option[Zipper[Int]] = List(1,2,3,4).toZipper
You can move the focus of the zipper using methods on Zipper, for example, you can move to the next offset from the current focus.
val z2: Option[Zipper[Int]] = z >>= (_.next)
This is like List.tail except that it remembers where it has been.
Then, once you have your chosen element in focus, you can modify the elements around the focus.
val swappedWithNext: Option[Zipper[Int]] =
for (x <- z2;
y <- x.delete)
yield y.insertLeft(x.focus)
Note: this is with the latest Scalaz trunk head, in which a bug with Zipper's tail-recursive find and move methods has been fixed.
The method you want is then just:
def swapWithNext[T](l: List[T], p: T => Boolean) : List[T] = (for {
z <- l.toZipper
y <- z.findZ(p)
x <- y.delete
} yield x.insertLeft(y.focus).toStream.toList) getOrElse l
This matches an element based on a predicate p. But you can go further and consider all nearby elements as well. For instance, to implement an insertion sort.
A generic version of Landei's:
import scala.collection.generic.CanBuildFrom
import scala.collection.SeqLike
def swapWithNext[A,CC](cc: CC, e: A)(implicit w1: CC => SeqLike[A,CC],
w2: CanBuildFrom[CC,A,CC]): CC = {
val seq: SeqLike[A,CC] = cc
val (h,t) = seq.span(_ != e)
val (m,l) = (t.head,t.tail)
if(l.isEmpty) cc
else (h :+ l.head :+ m) ++ l.tail
}
some usages:
scala> swapWithNext(List(1,2,3,4),3)
res0: List[Int] = List(1, 2, 4, 3)
scala> swapWithNext("abcdef",'d')
res2: java.lang.String = abcedf
scala> swapWithNext(Array(1,2,3,4,5),2)
res3: Array[Int] = Array(1, 3, 2, 4, 5)
scala> swapWithNext(Seq(1,2,3,4),3)
res4: Seq[Int] = List(1, 2, 4, 3)
scala>
An alternative implementation for venechka's method:
def swapWithNext[T](l: List[T], e: T): List[T] = {
val (h,t) = l.span(_ != e)
h ::: t.tail.head :: e :: t.tail.tail
}
Note that this fails with an error if e is the last element.
If you know both elements, and every element occurs only once, it gets more elegant:
def swap[T](l: List[T], a:T, b:T) : List[T] = l.map(_ match {
case `a` => b
case `b` => a
case e => e }
)
How about :
val identifierPosition = 3;
val l = "this is a identifierhere here";
val sl = l.split(" ").toList;
val elementAtPos = sl(identifierPosition)
val swapped = elementAtPos :: dropIndex(sl , identifierPosition)
println(swapped)
def dropIndex[T](xs: List[T], n: Int) : List[T] = {
val (l1, l2) = xs splitAt n
l1 ::: (l2 drop 1)
}
kudos to http://www.scala-lang.org/old/node/5286 for dropIndex function