Scala generic types - scala

I there, I'm trying to combine the Command and Chain of responsibility patterns with Scala style.
Basically, I would like to have one Executor who pass the command trough the chain and return the result. A command is anything that return a T :
class class Invoker {
type Command[T] = () => T
val handlers = new mutable.ListBuffer[PartialFunction[() => T, T]]
def invoke[T](command: => T): Future[T] = Future {
handlers.find(_.isDefinedAt(command)).map(_.apply(command))
}
}
But, because I'm a scala beginner, I have problems with the generic types for the list of handlers. I cannot figure how to define T in the declaration of handlers so that the invoke command return the correct type (wich should be T)
Can someone help me to implement this pattern ?

There are several sketchy places, but I think the closest you'll get to what you want would be (Though, it will not work, see below):
import scala.collection.mutable
import scala.concurrent.Future
object Invoker {
val handlers = new mutable.ListBuffer[PartialFunction[Any, Any]]
def invoke[T](command: () => T): Future[T] = Future {
handlers.collectFirst {
case pf if pf.isDefinedAt(command) => pf(command)
}.fold(throw new Exception("failure")) {
_.asInstanceOf[T]
}
}
}
However,
It will not work because, the partial functions or more specifically pattern matching will most certainly not work as you expect for Function0
You loose most of your type information through erasure and have to rely upon what you know about the partial functions.
In scala, the need to call asInstanceOf is a good indicator that something can be done better.
#1
When you define a list of partial functions that match on Function0 like for example this:
val T1: () => Int = () => 1
val T2: () => Int = () => 2
val T3: () => Int = () => 3
val pfs: Seq[PartialFunction[Any, Any]] = Seq(
PartialFunction[Any, Any] {
case T1 => T1()
},
PartialFunction[Any, Any] {
case T2 => T2()
},
PartialFunction[Any, Any] {
case T3 => T3()
}
)
Trying to find a match for any function literal will lead to a MatchError:
def invoke[T](c: () => T): T = {
pfs.collectFirst {
case pf if pf.isDefinedAt(c) => pf(c)
}.fold(throw new Exception("failure")) {
_.asInstanceOf[T]
}
}
invoke(() => 1) |-> scala.MatchError: <function0> (of class abc.A$A290$A$A290$$anonfun$ti1$1)
This would only work if you define Constants for allowed functions and only use those constants, when you call invoke.
You could define them with the Invoker object:
object Invoker {
val SomeCommand = () => 5 + 5
val AnotherCommand = () => 5 * 5
}
But that would utterly eliminate any flexibility.
FINALLY:
If you want to be able to perform any Command then why maintain a list of handlers anyway?
object Invoker {
def invoke[T](command: () => T): Future[T] = Future {
command()
}
}
should be sufficient for that.

Related

Generating adaptors for higher-kinded interfaces

I often find myself in a scenario where I have defined an interface like so:
trait FooInterface [T[_]] {
def barA (): T[Int]
def barB (): T[Int]
def barC (): T[Int]
}
I then write a few different implementations each typed on the Higher Kinded Type that makes the most sense for that particular implementation:
object FooImpl1 extends FooInterface[Option] { ... }
object FooImpl2 extends FooInterface[Future] { ... }
object FooImpl3 extends FooInterface[({type X[Y] = ReaderT[Future, Database, Y]})#X] { ... }
All implementations are perfectly valid, all return their results wrapped in a particular Higher Kinded Type.
I then often come to writing some business logic, let's say that in the block of logic I am working with is using Future as a context, I might write something like this:
val foo: FooInterface[Future] = ???
def fn (): Future[Int] = Future { 42 }
val result: Future[Int] = for {
x <- foo.barA ()
y <- foo.barB ()
z <- foo.barC ()
w <- fn ()
} yield x + y + z + w
The above code would work really well with FooImpl2 however the other implementations do not slot in directly. In this scenario I always wind up writing simple adapters:
object FooImpl1Adapter extends FooInterface[Future] {
val t = new Exception ("Foo impl 1 failed.")
def barA (): Future[Int] = FooImpl1.barA () match {
case Some (num) => Future.successful (num)
case None => Future.failed (t)
}
def barB (): Future[Int] = FooImpl1.barB () match {
case Some (num) => Future.successful (num)
case None => Future.failed (t)
}
def barC (): Future[Int] = FooImpl1.barC () match {
case Some (num) => Future.successful (num)
case None => Future.failed (t)
}
}
case class FooImpl3Adapter (db: Database) extends FooInterface[Future] {
def barA (): Future[Int] = FooImpl3.barA ().run (db)
def barB (): Future[Int] = FooImpl3.barB ().run (db)
def barC (): Future[Int] = FooImpl3.barC ().run (db)
}
Writing adapters is fine but it involves a lot of boilerplate, especially for interfaces with lots of functions; what's more is that each method gets the exactly same adaptation treatment for each method. What I really want to do is lift an adaptor implementation from an existing implementation, only specify in adaption mechanism once.
I guess I want to be able to write something like this:
def generateAdapterFn[X[_], Y[_]] (implx: FooInterface[X])(f: X[?] => Y[?]): FooInterface[Y] = ???
So I could use it like so:
val fooImpl1Adapter: FooInterface[Future] = generateAdapterFn [?, Future] () { z => z match {
case Some (obj) => Future.successful (obj)
case None => Future.failed (t)
}}
The question is: How could I write the generateAdapterFn function?
I'm not really sure how to approach solving this, or if there are other common patterns or solutions to my problem. I suspect that to write the generateAdapterFn function I desire I would need to write a macro? If so how might that be done?
What you are looking for is a natural transformation from X to Y (what you called X[?] => Y[?]). In Cats is called a FunctionK (with the popular type alias ~>).
You could define a natural transformation between Option and Future as :
import cats.arrow.FunctionK
import scala.concurrent.Future
val option2future = new FunctionK[Option, Future] {
def apply[A](opt: Option[A]): Future[A] = opt match {
case Some(obj) => Future.succesful(obj)
case None => Future.failed(new Exception("none")) // t ??
}
}
With the kind projector compiler plugin this could be written more concise as :
val opt2fut = λ[FunctionK[Option, Future]]{
case Some(obj) => Future.succesful(obj)
case None => Future.failed(new Exception("none")) // t ??
}
Your generateAdapter function could then look like :
import cats.~>
def generateAdapter[X[_], Y[_]](implx: FooInterface[X])(f: X ~> Y): FooInterface[Y] =
new FooInterface[Y] {
def barA: Y[Int] = f(implx.barA)
def barB: Y[Int] = f(implx.barB)
def barC: Y[Int] = f(implx.barC)
}
You should then be able to create a FooInterface[Future]] as :
val fooFuture = generateAdapter(FooImpl1)(opt2fut)
Unrelated, you might be interested to read something about the free monad, which is used to solve similar problems as the one you are facing now.
Keep the code polymorphic for as long as possible. Instead of
val result: Future[Int] = for {
x <- foo.barA ()
y <- foo.barB ()
z <- foo.barC ()
w <- fn ()
} yield x + y + z + w
write
import scalaz.Monad
import scalaz.syntax.monad._
// or
import cats.Monad
import cats.syntax.all._
def result[M[_]: Monad](foo: FooInterface[M], fn: () => M[Int]): M[Int] = for {
x <- foo.barA ()
y <- foo.barB ()
z <- foo.barC ()
w <- fn ()
} yield x + y + z + w
This way, you avoid writing adapters for FooInterface altogether and only transform the final value (via a natural transformation (see Peter Neyens' answer) or also quite easily directly).
Expanding on Peter Neyen's answer (which I've marked as correct as it answers the important part of my question), here's a proof of concept for how generate the adapter at runtime using reflection:
def generateAdapterR[X[_], Y[_]](implx: FooInterface[X])(implicit
f: X ~> Y): FooInterface[Y] = {
import java.lang.reflect.{InvocationHandler, Method, Proxy}
object ProxyInvocationHandler extends InvocationHandler {
def invoke (
proxy: scala.AnyRef,
method: Method,
args: Array[AnyRef]): AnyRef = {
val fn = implx.getClass.getMethod (
method.getName,
method.getParameterTypes: _*)
val x = fn.invoke (implx, args: _*)
val fx = f.getClass.getMethods ()(0)
fx.invoke (f, x)
}
}
Proxy.newProxyInstance(
classOf[FooInterface[Y]].getClassLoader,
Array(classOf[FooInterface[Y]]),
ProxyInvocationHandler
).asInstanceOf[FooInterface[Y]]
}
Ideally it would be possible to type this function on T[_] as well, T being the type of the interface, so the function could be use to generate adaptors for any higher kinded interfaces at runtime.
Something like:
def genericGenerateAdapterR[T[_], X[_], Y[_]](implx: T[X[_]])(implicit
f: X ~> Y): T[Y[_]] = ???
Not really sure if that would be how to write it though...
I think the ideal solution would be to have a compiler plugin that generates the code in Peter Neyen's solution, avoiding reflection and avoiding boilerplate.

Can we have an array of by-name-parameter functions?

In Scala we have a by-name-parameters where we can write
def foo[T](f: => T):T = {
f // invokes f
}
// use as:
foo(println("hello"))
I now want to do the same with an array of methods, that is I want to use them as:
def foo[T](f:Array[ => T]):T = { // does not work
f(0) // invokes f(0) // does not work
}
foo(println("hi"), println("hello")) // does not work
Is there any way to do what I want? The best I have come up with is:
def foo[T](f:() => T *):T = {
f(0)() // invokes f(0)
}
// use as:
foo(() => println("hi"), () => println("hello"))
or
def foo[T](f:Array[() => T]):T = {
f(0)() // invokes f(0)
}
// use as:
foo(Array(() => println("hi"), () => println("hello")))
EDIT: The proposed SIP-24 is not very useful as pointed out by Seth Tisue in a comment to this answer.
An example where this will be problematic is the following code of a utility function trycatch:
type unitToT[T] = ()=>T
def trycatch[T](list:unitToT[T] *):T = list.size match {
case i if i > 1 =>
try list.head()
catch { case t:Any => trycatch(list.tail: _*) }
case 1 => list(0)()
case _ => throw new Exception("call list must be non-empty")
}
Here trycatch takes a list of methods of type ()=>T and applies each element successively until it succeeds or the end is reached.
Now suppose I have two methods:
def getYahooRate(currencyA:String, currencyB:String):Double = ???
and
def getGoogleRate(currencyA:String, currencyB:String):Double = ???
that convert one unit of currencyA to currencyB and output Double.
I use trycatch as:
val usdEuroRate = trycatch(() => getYahooRate("USD", "EUR"),
() => getGoogleRate("USD", "EUR"))
I would have preferred:
val usdEuroRate = trycatch(getYahooRate("USD", "EUR"),
getGoogleRate("USD", "EUR")) // does not work
In the example above, I would like getGoogleRate("USD", "EUR") to be invoked only if getYahooRate("USD", "EUR") throws an exception. This is not the intended behavior of SIP-24.
Here is a solution, although with a few restrictions compared to direct call-by-name:
import scala.util.control.NonFatal
object Main extends App {
implicit class Attempt[+A](f: => A) {
def apply(): A = f
}
def tryCatch[T](attempts: Attempt[T]*): T = attempts.toList match {
case a :: b :: rest =>
try a()
catch {
case NonFatal(e) =>
tryCatch(b :: rest: _*)
}
case a :: Nil =>
a()
case Nil => throw new Exception("call list must be non-empty")
}
def a = println("Hi")
def b: Unit = sys.error("one")
def c = println("bye")
tryCatch(a, b, c)
def d: Int = sys.error("two")
def e = { println("here"); 45 }
def f = println("not here")
val result = tryCatch(d, e, f)
println("Result is " + result)
}
The restrictions are:
Using a block as an argument won't work; only the last expression of the block will be wrapped in an Attempt.
If the expression is of type Nothing (e.g., if b and d weren't annotated), the conversion to Attempt is not inserted since Nothing is a subtype of every type, including Attempt. Presumably the same would apply for an expression of type Null.
As of Scala 2.11.7, the answer is no. However, there is SIP-24, so in some future version your f: => T* version may be possible.

What type parameters should I use to make List.map work with delimited continuations?

I'm basically following the example given at the Scala API page for delimited continuations. The code below works fine:
import scala.util.continuations._
import scala.collection.mutable.HashMap
val sessions = new HashMap[Int, Int=>Unit]
def ask(prompt: String): Int #cps[Unit] = shift {
ret: (Int => Unit) => {
val id = sessions.size
printf("%s\nrespond with: submit(0x%x, ...)\n", prompt, id)
sessions += id -> ret
}
}
def submit(id: Int, addend: Int): Unit = {
sessions.get(id) match {
case Some(continueWith) => continueWith(addend)
}
}
def go = reset {
println("Welcome!")
val first = ask("Please give me a number")
val second = ask("Please enter another number")
printf("The sum of your numbers is: %d\n", first + second)
}
However, when I modify go to the following:
def go = reset {
println("Welcome!")
List("First?","Second?").map[Int #cps[Unit]](ask)
}
I get this error:
error: wrong number of type parameters for method map: [B, That](f: String => B)
(implicit bf: scala.collection.generic.CanBuildFrom[List[String],B,That])That
List("First?","Second?").map[Int #cps[Unit]](ask)
^
Adding Any as a second type parameter doesn't help. Any idea what types I should be supplying?
The reason is that this is simply not possible without creating a CPS-transformed map method on List: the CPS annotations make the compiler turn your methods “inside out” in order to pass the continuation back to where it is needed and the standard List.map does not obey the transformed contract. If you want to have your mind wrapped in Klein bottles for a while you may look at the class files produced from your source, in particular the method signatures.
This is the primary reason why the CPS plugin will never be a complete generic solution to this problem, which is not due to a deficiency but caused by an inherent mismatch between “straight” code and continuation passing style.
You need to give correct parameter for the CanBuildFrom implicit to be found:
List("First?","Second?").map[Int #cps[Unit], List[Int #cps[Unit]](ask)
But do you really need to be explicit about type? maybe just do .map(ask) will work.
Here's the closest thing I could work out. It uses shiftR to reify the continuation rather than reset it, uses a foldRight to construct the suspended continuation chain, uses a shift/reset block to get the continuation after the suspension, and an "animate" method to kick off the suspended continuation.
import scala.collection.mutable.HashMap
import scala.util.continuations._
val sessions = new HashMap[Int, (Unit=>Unit, Int)]
val map = new HashMap[Int, Int]
def ask(pair:(String, Int)) = pair match {
case (prompt, index) => shiftR { (ret: Unit => Unit) => {
val id = sessions.size
printf("%s\nrespond with: submit(0x%x, ...)\n", prompt, id)
sessions += id -> (ret, index)
()
}}
}
def submit(id: Int, addend: Int): Unit = {
sessions.get(id) match {
case Some((continue, index)) => { map.put(index, addend); continue() }
}
}
def sum(m:HashMap[Int,Int]) : Int = {
m.fold[(Int, Int)]((0, 0))((a, b) => (0, {a._2+b._2}))._2
}
type Suspended = ControlContext[Unit,Unit,Unit]
class AnimateList(l:List[Suspended]) {
def suspend(k: => Unit) = (c: Unit) => k
def animate(k:Unit => Unit): Unit = {
l.foldRight(k)(
(elem: Suspended, acc: Unit => Unit) => suspend(elem.fun(acc, ex => ())))()
}
}
implicit def listToAnimateList(l:List[Suspended]) = new AnimateList(l)
reset {
val conts = List("First?","Second?","Third?").zipWithIndex.map(ask)
shift { conts.animate }
println(sum(map))
}

How to overload scala function apply methods

As a follow on to: scala loan pattern, optional function param
What would the proper syntax be to move the withLoaner param to overloaded apply methods? I've tried several versions of the following unsuccessfully. Also, any insights into my error conceptually very appreciated.
def withLoaner = new {
def apply(n:Int, op: Int => String):String = (1 to n).map(op).mkString("\n")
def apply(n:Int, op: () => String):String = apply{n, i:Int => op()} // no compile
def apply(op: () => String):String = apply{1, i:Int => op()} // no compile
}
When passing multiple parameters, you must use parenthesis around them. Using {} only works for single parameters.
Also, when using function literals, if you specify type, you have to put all of the functions parameters inside parenthesis.
So,
def withLoaner = new {
def apply(n:Int, op: Int => String):String = (1 to n).map(op).mkString("\n")
def apply(n:Int, op: () => String):String = apply(n, i => op()) // no type on i
def apply(op: () => String):String = apply(1, (i: Int) => op()) // parenthesis around parameters
}
2 little changes:
Use ( instead of { when calling apply:
apply(.......)
Use ( around the arg to an implicit function:
apply(1, (i:Int) => op())

Help me understand this Scala code: scalaz IO Monad and implicits

This is a followup to this question.
Here's the code I'm trying to understand (it's from http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/):
object io {
sealed trait IO[A] {
def unsafePerformIO: A
}
object IO {
def apply[A](a: => A): IO[A] = new IO[A] {
def unsafePerformIO = a
}
}
implicit val IOMonad = new Monad[IO] {
def pure[A](a: => A): IO[A] = IO(a)
def bind[A,B](a: IO[A], f: A => IO[B]): IO[B] = IO {
implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
(x:A) => () => f(x).unsafePerformIO)()
}
}
}
This code is used like this (I'm assuming an import io._ is implied)
def bufferFile(f: File) = IO { new BufferedReader(new FileReader(f)) }
def closeReader(r: Reader) = IO { r.close }
def bracket[A,B,C](init: IO[A], fin: A => IO[B], body: A => IO[C]): IO[C] = for { a <- init
c <- body(a)
_ <- fin(a) } yield c
def enumFile[A](f: File, i: IterV[String, A]): IO[IterV[String, A]] = bracket(bufferFile(f),
closeReader(_:BufferedReader),
enumReader(_:BufferedReader, i))
I'm now trying to understand the implicit val IOMonad definition. Here's how I understand it. This is a scalaz.Monad, so it needs to define pure and bind abstract values of the scalaz.Monad trait.
pure takes a value and turns it into a value contained in the "container" type. For example it could take an Int and return a List[Int]. This seems pretty simple.
bind takes a "container" type and a function that maps the type that the container holds to another type. The value that is returned is the same container type, but it's now holding a new type. An example would be taking a List[Int] and mapping it to a List[String] using a function that maps Ints to Strings. Is bind pretty much the same as map?
The implementation of bind is where I'm stuck. Here's the code:
def bind[A,B](a: IO[A], f: A => IO[B]): IO[B] = IO {
implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
(x:A) => () => f(x).unsafePerformIO)()
}
This definition takes IO[A] and maps it to IO[B] using a function that takes an A and returns an IO[B]. I guess to do this, it has to use flatMap to "flatten" the result (correct?).
The = IO { ... } is the same as
= new IO[A] {
def unsafePerformIO = implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
(x:A) => () => f(x).unsafePerformIO)()
}
}
I think?
the implicitly method looks for an implicit value (value, right?) that implements Monad[Function0]. Where does this implicit definition come from? I'm guessing this is from the implicit val IOMonad = new Monad[IO] {...} definition, but we're inside that definition right now and things get a little circular and my brain starts to get stuck in an infinite loop :)
Also, the first argument to bind (() => a.unsafePerformIO) seems to be a function that takes no parameters and returns a.unsafePerformIO. How should I read this? bind takes a container type as its first argument, so maybe () => a.unsafePerformIO resolves to a container type?
IO[A] is intended to represent an Action returning an A, where the result of the Action may depend on the environment (meaning anything, values of variables, file system, system time...) and the execution of the action may also modify the environment. Actually, scala type for an Action would be Function0. Function0[A] returns an A when called and it is certainly allowed to depend on and modify the environment. IO is Function0 under another name, but it is intended to distinguish (tag?) those Function0 which depends on the environment from the other ones, which are actually pure value (if you say f is a function[A] which always returns the same value, without any side effect, there is no much difference between f and its result). To be precise, it is not so much that function tagged as IO must have side effect. It is that those not so tagged must have none. Note however than wrapping impure functions in IO is entirely voluntary, there is no way you will have a guarantee when you get a Function0 that it is pure. Using IO is certainly not the dominant style in scala.
pure takes a value and turns it into a value contained in the
"container" type.
Quite right, but "container" may mean quite a lot of things. And the one returned by pure must be as light as possible, it must be the one that makes no difference. The point of list is that they may have any number of values. The one returned by pure must have one. The point of IO is that it depends on and affect the environment. The one returned by pure must do no such thing. So it is actually the pure Function0 () => a, wrapped in IO.
bind pretty much the same as map
Not so, bind is the same as flatMap. As you write, map would receive a function from Int to String, but here you have the function from Int to List[String]
Now, forget IO for a moment and consider what bind/flatMap would mean for an Action, that is for Function0.
Let's have
val askUserForLineNumber: () => Int = {...}
val readingLineAt: Int => Function0[String] = {i: Int => () => ...}
Now if we must combine, as bind/flatMap does, those items to get an action that returns a String, what it must be is pretty clear: ask the reader for the line number, read that line and returns it. That would be
val askForLineNumberAndReadIt= () => {
val lineNumber : Int = askUserForLineNumber()
val readingRequiredLine: Function0[String] = readingLineAt(line)
val lineContent= readingRequiredLine()
lineContent
}
More generically
def bind[A,B](a: Function0[A], f: A => Function0[B]) = () => {
val value = a()
val nextAction = f(value)
val result = nextAction()
result
}
And shorter:
def bind[A,B](a: Function0[A], f: A => Function0[B])
= () => {f(a())()}
So we know what bind must be for Function0, pure is clear too. We can do
object ActionMonad extends Monad[Function0] {
def pure[A](a: => A) = () => a
def bind[A,B](a: () => A, f: A => Function0[B]) = () => f(a())()
}
Now, IO is Function0 in disguise. Instead of just doing a(), we must do a.unsafePerformIO. And to define one, instead of () => body, we write IO {body}
So there could be
object IOMonad extends Monad[IO] {
def pure[A](a: => A) = IO {a}
def bind[A,B](a: IO[A], f: A => IO[B]) = IO {f(a.unsafePerformIO).unsafePerformIO}
}
In my view, that would be good enough. But in fact it repeats the ActionMonad. The point in the code you refer to is to avoid that and reuse what is done for Function0 instead. One goes easily from IO to Function0 (with () => io.unsafePerformIo) as well as from Function0 to IO (with IO { action() }). If you have f: A => IO[B], you can also change that to f: A => Function0[B], just by composing with the IO to Function0 transform, so (x: A) => f(x).unsafePerformIO.
What happens here in the bind of IO is:
() => a.unsafePerformIO: turn a into a Function0
(x:A) => () => f(x).unsafePerformIO): turn f into an A => Function0[B]
implicitly[Monad[Function0]]: get the default monad for Function0, the very same as the ActionMonad above
bind(...): apply the bind of the Function0 monad to the arguments a and f that have just been converted to Function0
The enclosing IO{...}: convert the result back to IO.
(Not sure I like it much)