Say I have these declarations:
val f1 = EventFilter.info(pattern = s"starting calls: three_step.ps, three_step.ps2, three_step.ps3", occurrences = 1)
val f2 = EventFilter.info(pattern = s"starting calls: three_step.cgrep, three_step.wc", occurrences = 1)
val f = Seq(f1, f2)
Right now I can do this:
f1.intercept { f2.intercept {
... Some code here ...
}}
However, I want that first line to be expressed as a function of val f = Seq(f1, f2) rather than of f1 and f2 directly. I'm not sure how to express this but I want to be able to do this for any Seq[EventFilter] objects
I'm assuming that intercept takes in and returns the same type here, since that's the only way to chain functions in this way.
Most generally, you can use a foldLeft or foldRight to accomplish this sort of chaining.
eventFilters.foldLeft(startingValue) {
case (acc, next) => next.intercept(acc)
}
You might also be interested in Future.chain[T], which chains together a sequence of functions T => T. If you would want to use that, you need to make your Seq[EventFilter] into a Seq[Foo => Foo] (where Foo is the parameter/return type of intercept):
val interceptFuncs = eventFilters.map(_.intercept _) //Seq[Foo => Foo]
Function.chain(interceptFuncs)(startingValue)
This should work in scalaz:
implicit def endofunctionMonoid[A] = new Monoi[Function1[A, A]] {
def append(f1: Function1[A, A], f2: => Function1[A, A]): Function1[A, A] =
f1 _ compose f2 _
def zero: Function1[A, A] = a => a
}
val fs = List(f1, f2) // event filters
fs.foldMap { _.intercept _ } // map the list to Function1s and accumulate via the semigroup operation.
Related
Background
I have been reading the book Functional Programming in Scala, and have some questions regarding the content in Chapter 7: Purely functional parallelism.
Here is the code for the answers in the book: Par.scala, but I am confused about certain part of it.
Here is the first part of the code of Par.scala, which stands for Parallelism:
import java.util.concurrent._
object Par {
type Par[A] = ExecutorService => Future[A]
def unit[A](a: A): Par[A] = (es: ExecutorService) => UnitFuture(a)
private case class UnitFuture[A](get: A) extends Future[A] {
def isDone = true
def get(timeout: Long, units: TimeUnit): A = get
def isCancelled = false
def cancel(evenIfRunning: Boolean): Boolean = false
}
def map2[A, B, C](a: Par[A], b: Par[B])(f: (A, B) => C): Par[C] =
(es: ExecutorService) => {
val af = a(es)
val bf = b(es)
UnitFuture(f(af.get, bf.get))
}
def fork[A](a: => Par[A]): Par[A] =
(es: ExecutorService) => es.submit(new Callable[A] {
def call: A = a(es).get
})
def lazyUnit[A](a: => A): Par[A] =
fork(unit(a))
def run[A](es: ExecutorService)(a: Par[A]): Future[A] = a(es)
def asyncF[A, B](f: A => B): A => Par[B] =
a => lazyUnit(f(a))
def map[A, B](pa: Par[A])(f: A => B): Par[B] =
map2(pa, unit(()))((a, _) => f(a))
}
The simplest possible model for Par[A] might be ExecutorService => Future[A], and run simply returns the Future.
unit promotes a constant value to a parallel computation by returning a UnitFuture, which is a simple implementation of Future that just wraps a constant value.
map2 combines the results of two parallel computations with a binary function.
fork marks a computation for concurrent evaluation. The evaluation won’t actually occur until forced by run. Here is with its simplest and most natural implementation of it. Even though it has its problems, let's first put them aside.
lazyUnit wraps its unevaluated argument in a Par and marks it for concurrent evaluation.
run extracts a value from a Par by actually performing the computation.
asyncF converts any function A => B to one that evaluates its result asynchronously.
Questions
The fork is the function confuses me a lot here, because it takes a lazy argument, which will be evaluated later when it is called. Then my questions are more about when we should use this fork, i.e., when we need lazy-evaluation and when we need to have the value directly.
Here is an exercise from the book:
EXERCISE 7.5
Hard: Write this function, called sequence. No additional primitives are required. Do not call run.
def sequence[A](ps: List[Par[A]]): Par[List[A]]
And here is the answers (offered here).
First
def sequence_simple[A](l: List[Par[A]]): Par[List[A]] =
l.foldRight[Par[List[A]]](unit(List()))((h, t) => map2(h, t)(_ :: _))
What is the different between above code and the following:
def sequence_simple[A](l: List[Par[A]]): Par[List[A]] =
l.foldLeft[Par[List[A]]](unit(List()))((t, h) => map2(h, t)(_ :: _))
Additionally
def sequenceRight[A](as: List[Par[A]]): Par[List[A]] =
as match {
case Nil => unit(Nil)
case h :: t => map2(h, fork(sequenceRight(t)))(_ :: _)
}
def sequenceBalanced[A](as: IndexedSeq[Par[A]]): Par[IndexedSeq[A]] = fork {
if (as.isEmpty) unit(Vector())
else if (as.length == 1) map(as.head)(a => Vector(a))
else {
val (l,r) = as.splitAt(as.length/2)
map2(sequenceBalanced(l), sequenceBalanced(r))(_ ++ _)
}
}
In sequenceRight, fork is used when recursive function is directly called. However, in sequenceBalanced, fork is used outside of the whole function body.
Then, what is the differences or above code and the following (where we switched the places of fork):
def sequenceRight[A](as: List[Par[A]]): Par[List[A]] = fork {
as match {
case Nil => unit(Nil)
case h :: t => map2(h, sequenceRight(t))(_ :: _)
}
}
def sequenceBalanced[A](as: IndexedSeq[Par[A]]): Par[IndexedSeq[A]] =
if (as.isEmpty) unit(Vector())
else if (as.length == 1) map(as.head)(a => Vector(a))
else {
val (l,r) = as.splitAt(as.length/2)
map2(fork(sequenceBalanced(l)), fork(sequenceBalanced(r)))(_ ++ _)
}
Finally, given the sequence defined above, we have the following function:
def parMap[A,B](ps: List[A])(f: A => B): Par[List[B]] = fork {
val fbs: List[Par[B]] = ps.map(asyncF(f))
sequence(fbs)
}
I would like to know, can I also implement the function in the following way, which is by applying the lazyUnit defined in the beginning? Is this implementation lazyUnit(ps.map(f)) lazy?
def parMapByLazyUnit[A, B](ps: List[A])(f: A => B): Par[List[B]] =
lazyUnit(ps.map(f))
I did not completely understand your doubt. But I see a major problem with the following solution,
def parMapByLazyUnit[A, B](ps: List[A])(f: A => B): Par[List[B]] =
lazyUnit(ps.map(f))
To understand the problem lets look at def lazyUnit,
def fork[A](a: => Par[A]): Par[A] =
(es: ExecutorService) => es.submit(new Callable[A] {
def call: A = a(es).get
})
def lazyUnit[A](a: => A): Par[A] =
fork(unit(a))
So... lazyUnit takes an expression of type => A and submits it to ExecutorService to get evaluated. And returns the wrapped result of this parallel computation as Par[A].
In parMap for every element of ps: List[A], we not only have to evaluate the corresponding mapping using the function f: A => B but we have to do these evaluations in parallel.
But our solution lazyUnit(ps.map(f)) will submit the whole { ps.map(f) } evaluation as a single task to our ExecutionService. Which means we are not doing it in parallel.
What we need to do is make sure that for each element a in ps: [A], the function f: A => B is executed as a separate task for our ExecutorService.
Now, as we learned from our implementation is that we can run an expression of type exp: => A by using lazyUnit(exp) to get a result: Par[A].
So, we will do exactly that for every a: A in ps: List[A],
val parMappedTmp = ps.map( a => lazyUnit(f(a) ) )
// or
val parMappedTmp = ps.map( a => asyncF(f)(a) )
// or
val parMappedTmp = ps.map(asyncF(f))
But, Now our parMappedTmp is a List[Par[B]] and whereas we needed a Par[List[B]]
So, you will need a function with the following signature to get what you wanted,
def sequence[A](ps: List[Par[A]]): Par[List[A]]
Once you have it,
val parMapped = sequence(parMappedTmp)
Given this spinet of code in Scala:
val mapMerge : (Map[VertexId, Factor], Map[VertexId, Factor]) => Map[VertexId, Factor] = (d1, d2) => d1 ++ d2
That can be shortened to:
val mapMerge : (Map[VertexId, Factor], Map[VertexId, Factor]) => Map[VertexId, Factor] = _ ++ _
What actually the code does is renaming the operator ++ of Map[VertexId, Factor] and therefore: Is there a way to assign that operator to the variable? Like in this imaginary example:
val mapMerge : (Map[VertexId, Factor], Map[VertexId, Factor]) => Map[VertexId, Factor] = Map.++
And probably with type inference it would enough to write
val mapMerge = Map[VertexId,Factor].++
Thanks
Unfortunately, no, because the "operators" in Scala are instance methods — not functions from a typeclass, like in Haskell.
Whey you write _ ++ _, you are creating a new 2-argument function(lambda) with unnamed parameters. This is equivalent to (a, b) => a ++ b, which is in turn equivalent to (a, b) => a.++(b), but not to (a, b) => SomeClass.++(a, b).
You can emulate typeclasses by using implicit arguments (see "typeclasses in scala" presentation)
You can pass "operators" like functions — which are not really operators. And you can have operators which look the same. See this example:
object Main {
trait Concat[A] { def ++ (x: A, y: A): A }
implicit object IntConcat extends Concat[Int] {
override def ++ (x: Int, y: Int): Int = (x.toString + y.toString).toInt
}
implicit class ConcatOperators[A: Concat](x: A) {
def ++ (y: A) = implicitly[Concat[A]].++(x, y)
}
def main(args: Array[String]): Unit = {
val a = 1234
val b = 765
val c = a ++ b // Instance method from ConcatOperators — can be used with infix notation like other built-in "operators"
println(c)
val d = highOrderTest(a, b)(IntConcat.++) // 2-argument method from the typeclass instance
println(d)
// both calls to println print "1234765"
}
def highOrderTest[A](x: A, y: A)(fun: (A, A) => A) = fun(x, y)
}
Here we define Concat typeclass and create an implementation for Int and we use operator-like name for the method in typeclass.
Because you can implement a typeclass for any type, you can use such trick with any type — but that would require writing quite some supporting code, and sometimes it is not worth the result.
Piping things in Scala is often very simple - think map for collections, composeand andThen for function composition.
However, I don't seem to find a way to combine the two. I have a function that returns an Option[Double]. I'd like to filter the Double value (reduce its precision) if it's there. andThen is close but needs me to handle the option thingy.
Is there a nice built-in way to deal with this in Scala 2.11?
class Temp( ff: (Object) => Option[Double] )
object Temp {
def apply( f: (Object) => Option[Double] ) = {
def cutTo5Digits(v: Double): Double = {
v - (v % 1e-5)
}
// call 'f', then pipe its output (if some) via 'cutTo5Digits'?
//
//new Temp( f map cutTo5Digits ) // nope
//new Temp( f _ andThen cutTo5Digits _ ) // would need option unwrapping
new Temp((o: Object) => f(o) map ((v: Double) => cutTo5Digits(v))) // compiles
}
}
I think that the best solution would be new Temp(f(_) map cutTo5Digits), what's wrong with it?
But if you want syntax like this: f map cutTo5Digits, then you can use Kleisli from scalaz, where f would be of type Kleisli[Option, Object, Double], i.e:
def apply( f: (Object) => Option[Double] ) = {
def cutTo5Digits(v: Double): Double = v - (v % 1e-5)
val ff = Kleisli(f)
new Temp(ff map cutTo5Digits) // or inline Kleisli(f) map ...
}
Or you can also make cutTo5Digits of type Double => Option[Double], such functions can be chained with Kliesli >=> method and you case can be rewritten as ff >=> cutTo5Digits.
If you want to use the andThen syntax, you can lift your function into a functor, for instance like this:
def liftOption[A, B](f: A => B): Option[A] => Option[B] = _.map(f(_))
To highlight the function composition, you can now write:
(f _) andThen liftOption(cutTo5Digits _)
If you make this conversion implicit, you can even use your original f _ andThen cutTo5Digits _. If you are using Scalaz, you should be able to lift your function via cutTo5Digits.lift[Option].
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
Let's assume this function:
def autoClosing(f: {def close();})(t: =>Unit) = {
t
f.close()
}
and this snippet:
val a = autoClosing(new X)(_)
a {
println("before close")
}
is it possible to curry the first part? Something like:
val a = autoClosing(_) { println("before close") }
so that I could send the objects on which close should be performed, and have the same block executed on them?
Yes, the snippet you have given works, as long as you give the type of the placeholder character.
Therefore, the code you are looking for is:
val a = autoClosing(_: {def close();}) { println("before close") }
which compiles and works as expected :).
A couple of notes:
You can make your life easier if you define a type alias for an AnyRef type having a close method, something like type Closeable = AnyRef {def close()}, or an appropriate interface.
The code snippet autoClosing(_: Closeable){ ... } is actually equivalent to the following expanded anonymous function: c: Closeable => autoClosing(c){ ... }. The wildcard character is just shorthand for a partially applied function. You need to give the type of the _ as the type inferer unfortunately cannot infer the type in this case.
Hope it helps,
-- Flaviu Cipcigan
Alternatively you can flip the parameters:
def flip[A1, A2, B](f: A1 => A2 => B): A2 => A1 => B = x1 => x2 => f(x2)(x1)
In your case:
val a = flip(autoClosing){ println("before close") }
Edit:
I've added some braces to help the human parser:
def flip[A1, A2, B](f: (A1 => (A2 => B))): (A2 => (A1 => B)) = {
x1 => (x2 => f(x2)(x1))
}
Flip converts a function (A1 => (A2 => B)) to (A2 => (A1 => B)).
scala> def x(x1 : Int)(x2 : Long) = 1.0 * x1 / x2
x: (Int)(Long)Double
scala> val f = flip(x)
f: (Long) => (Int) => Double = <function>
scala> val g = f(1)
g: (Int) => Double = <function>
scala> val h = g(2)
h: Double = 2.0
scala> x(1)(2)
res0: Double = 0.5
I'm happy to see so many people answering Scala questions nowadays. It does make it harder for me to come up with something, however. Here's an alternative to Flaviu's solution.
val a: {def close();} => Unit = autoClosing(_) { println("before close") }
Of course, the proper solution is to define autoClosing in a way compatible with how you are going to use it.