How to get Implicit parameter into scope when using currying - scala

Is there a way to pass an implicit parameter into a curried function. I am using a dirty fix (se below) but it is not pretty. I would love to be able to pass the implicit var "i" as a implicit param.
case class myLoaner() {
implicit val i = "How to get this val into scope within the session function"
def withCode[T](session: => T): Either[Exception, T] = {
try {
Right(session)
} catch {
case ex: Exception => {
Left(ex)
}
}
}
}
object Test {
def main(args: Array[String]) {
val r = myLoaner()
r.withCode {
implicit val imp = r.i // I want to get rid of this line of code and use the implict val defined above directly
val h = new Helper
h.run
}
}
class Helper {
def run(implicit i: String) {
println(i)
}
}
}

After val r = myLoaner(), you can write
import r.i
or
import r._
to do what you want. Alternatively, you can mark r itself implicit and provide this extra definition:
implicit def loanerString(implicit loaner: myLoaner): String = loaner.i
... but now a little bit too many implicits start floating around for my taste, so use that wisely. Sometimes too much implicit magic harms the readability and understandability of your code.

You can always pass implicit parameters directly, e.g. as h.run(r.i).

Related

Accessing implicit parameters explicitly at runtime

I'm trying to access an implicit parameter for a generic type. Scala is able to find the implicit just fine in the straightforward case by calling a method with an explicit generic type, such as with printGenericType[Person] below.
However, if I create a TypeTag[Person] and pass it to printGenericTypeGivenTypeTag, Scala is unable to find the implicit parameter.
case class Person(name: String)
case class Animal(age: Int)
implicit val p = Person("cory")
implicit val a = Animal(2)
def main(args: Array[String]): Unit = {
// Can find the implicit Person, prints "Hello Person(cory)"
printGenericType[Person]
// Can find the implicit Animal, prints "Hello Animal(2)"
printGenericType[Animal]
// See comment below
printNamedType("Person")
printNamedType("Animal")
}
def printGenericType[T](implicit t: T) = {
println(s"Hello $t")
}
def printGenericTypeGivenTypeTag[T](typeTag: TypeTag[T])(implicit t: T) = {
println(s"Hello $t")
}
def printNamedType[T](name: String) = {
val typetag: TypeTag[T] = getTypeTag[T](name)
// Cannot find the implicit of type T, compiler error
printGenericTypeGivenTypeTag(typetag)
}
def getTypeTag[T](name:String): TypeTag[T] = ... //Implementation irrelevant
If I understand correctly, Scala locates implicit parameters at compile time, so it makes sense that it can't find an implicit parameter for the generic type T at compile time.
However, I know that an implicit instance of T does exist. Is it possible to rewrite printGenericTypeGivenTypeTag in such a way as to find the implicit value for T? At runtime, the method has access to the actual type of T, so it seems it should be able to locate an implicit parameter of the same type that is in scope.
For the curious, the reasoning behind this is to avoid this:
name match {
case "Person" => printGenericType[Person]
case "Animal" => printGenericType[Animal]
}
To answer the question
You're not really wanting to pass the T implicitly, but rather the TypeTag, and not the T. Here's what I mean, and you're probably better off with an implicit value class.
implicit class GenericPrinter[T](val obj: T) extends AnyVal {
def printGenericType()(implicit tag: TypeTag[T]) = {
// do stuff with the tag
Console.println("Hello $obj")
}
}
val x: Person = Person(...)
x.printGenericType
Now solving the real problem
If you are trying to print case classes, I'd probably go down the implicit macro route for added convenience. It's really trivial to write up a macro that does this for us, e.g output a debug string based on all the constructor params of an arbitrary case class.
trait DeepPrinter[T <: Product with Serializable] {
/**
* Prints a deeply nested debug string for a given case class.
* This uses implicit macros to materialise the printer type class.
* In English, when we request for an implicit printer: DeepPrinter[T],
* the pre-defined compile time macro will generate this method for us
* based on the fields of the given case class.
*
* #param sep A separator to use to delimit the rows in a case class.
* #return A fully traced debug string so we can see how a case class looks like.
*/
def debugString(sep: String = "\n"): String
}
object DeepPrinter {
implicit def deepPrinter[T <: Product with Serializable] = macro DeepPrinterImpl.deepPrinterImpl[T]
}
And the macro is pretty trivial, looks kind of like this.
import language.experimental.macros
import scala.reflect.macros.blackbox
#macrocompat.bundle
class DeepPrinterImpl(val c: blackbox.Context) {
import c.universe._
object CaseField {
def unapply(symbol: TermSymbol): Option[(Name, Type)] = {
if (symbol.isVal && symbol.isCaseAccessor) {
Some(symbol.name -> symbol.typeSignature)
} else {
None
}
}
}
def fields(tpe: Type): Iterable[(Name, Type)] = {
tpe.decls.collect { case CaseField(nm, tpeSn) => nm -> tpeSn }
}
def materialize[T : c.WeakTypeTag]: c.Expr[DeepPrinter[T]] = {
val tpe = weakTypeOf[T]
val (names, types) = fields(tpe).unzip
// change the package name to the correct one here!
val tree = q"""
new com.bla.bla.DeepPrinter[$tpe] {
def debugString(sep: String = "\n") = Seq(..$names).mkString(sep)
}
"""
c.Expr[DeepPrinter[T]](tree)
}
}

Scala context bounds

Using context bounds in scala you can do stuff like
trait HasBuild[T] {
def build(buildable: T): Something
}
object Builders {
implict object IntBuilder extends HasBuild[Int] {
override def build(i: Int) = ??? // Construct a Something however appropriate
}
}
import Builders._
def foo[T: HasBuild](input: T): Something = implicitly[HasBuild[T]].build(1)
val somethingFormInt = foo(1)
Or simply
val somethingFromInt = implicitly[HasBuild[Int]].build(1)
How could I express the type of a Seq of any elements that have an appropriate implicit HasBuild object in scope? Is this possible without too much magic and external libraries?
Seq[WhatTypeGoesHere] - I should be able to find the appropriate HasBuild for each element
This obviously doesn't compile:
val buildables: Seq[_: HasBuild] = ???
Basically I'd like to be able to handle unrelated types in a common way (e.g.: build), without the user wrapping them in some kind of adapter manually - and enforce by the compiler, that the types actually can be handled. Not sure if the purpose is clear.
Something you can do:
case class HasHasBuild[A](value: A)(implicit val ev: HasBuild[A])
object HasHasBuild {
implicit def removeEvidence[A](x: HasHasBuild[A]): A = x.value
implicit def addEvidence[A: HasBuild](x: A): HasHasBuild[A] = HasHasBuild(x)
}
and now (assuming you add a HasBuild[String] for demonstration):
val buildables: Seq[HasHasBuild[_]] = Seq(1, "a")
compiles, but
val buildables1: Seq[HasHasBuild[_]] = Seq(1, "a", 1.0)
doesn't. You can use methods with implicit HasBuild parameters when you have only a HasHasBuild:
def foo1[A](x: HasHasBuild[A]) = {
import x.ev // now you have an implicit HasBuild[A] in scope
foo(x.value)
}
val somethings: Seq[Something] = buildables.map(foo1(_))
First things first, contrary to some of the comments, you are relying on context bounds. Requesting an implicit type class instance for a T is what you call a "context bound".
What you want is achievable, but not trivial and certainly not without other libraries.
import shapeless.ops.hlist.ToList
import shapeless._
import shapeless.poly_
object builder extends Poly1 {
implicit def caseGeneric[T : HasBuilder] = {
at[T](obj => implicitly[HasBuilder[T]].build(obj))
}
}
class Builder[L <: HList](mappings: L) {
def build[HL <: HList]()(
implicit fn: Mapper.Aux[builder.type, L, HL],
lister: ToList[Something]
) = lister(mappings map fn)
def and[T : HasBuilder](el: T) = new Builder[T :: L](el :: mappings)
}
object Builder {
def apply[T : HasBuilder](el: T) = new Builder(el :: HNil)
}
Now you might be able to do stuff like:
Builder(5).and("string").build()
This will call out the build methods from all the individual implcit type class instances and give you a list of the results, where every result has type Something. It relies on the fact that all the build methods have a lower upper bound of Something, e.g as per your example:
trait HasBuild[T] {
def build(buildable: T): Something
}

How to solve method delegation with scala implicits

How can i solve this simple problem. Class Conversion has a typed method from wich takes two type parameters A and B and returns a B from an A. I have defined some implicits in the companion object to provide default beahviour.
My Problem is when i try to forward the call to the Conversion class within another typed method which has the same signature it does not work. Here in my example i try to forward the call from function myFun to my Conversion class.
I got following error
not enough arguments for method from: (implicit f: A => B)
I am wondering why this makes any problems. Can someone explain me why and how to overcome this problem ?
Here is the code
object MyConversions {
implicit val IntToStr = (f:Int) => f.toString()
implicit val DoubleToStr = (f:Double) => f.toString()
implicit val BooleanToStr = (f:Boolean) => f.toString()
}
class Conversions{
def from[A,B](a:A)(implicit f:(A) => B) = {
f(a)
}
}
import MyConversions._;
def myFun[A,B](a:A){
// Error
new Conversions().from[A, B](a)
}
// Working
println( new Conversions().from[Int, String](3) )
The problem is that the Scala compiler cannot find an implicit value for the parameter f: (A) => B in the scope of myFun. What you have to do is to tell the compiler that myFun can only be called, when there is such a value available.
The following code should do the trick
object App {
trait Convertible[A, B] {
def convert(a: A): B
}
object Convertible {
implicit val int2String = new Convertible[Int, String] {
override def convert(a: Int): String = a.toString
}
implicit val float2String = new Convertible[Float, String] {
override def convert(a: Float): String = a.toString
}
}
def myFun[A ,B](a:A)(implicit converter: Convertible[A, B]): B = {
converter.convert(a)
}
def main(args: Array[String]): Unit = {
println(myFun(3))
}
}

Tunnel implicit parameter to call-by-name function body

Consider following code snippet:
object Example {
def run(f: => Unit): Unit = {
implicit val i = 1
f
}
def caller(): Unit =
run {
todo
}
def todo(implicit i: Int): Unit =
println(i)
}
which currently is not compiling with following message:
Error:(14, 13) could not find implicit value for parameter i: Int
todo
^
My question is it possible to make implicit parameter available to call-by-name function body?
EDIT
I tried make it working with macro implementation as suggested by Alexey Romanov
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
object Macros {
def run(f: => Unit): Unit = macro runImpl
def runImpl(c : Context)(f: c.Tree) = {
import c.universe._
q"""{
implicit val i: Int = 3
$f
}"""
}
}
object Example extends App {
Macros.run {
todo
}
def todo(implicit i: Int): Unit =
println(i)
}
Debugging macro i can see that it is correctly expanded into
{
implicit val i: Int = 3
Example.this.todo
}
Unfortunately it does not compiles as well with same error that implicit is not found.
Digging into issue i found discussions here and jira issues https://issues.scala-lang.org/browse/SI-5774
So question is the same: Is it possible to tunnel implicit into todo function in this case?
Simply said - no. implicit requires that it is obvious from the code what is going on. If you want anything to be passed to a function implicitly, it must have implicit parameter which is not the case of your f function.
This is a great source of wisdom related to implicit:
http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html
My question was more about why implicit defined in run is not tunneled into caller's run body
Because that's simply not how lexical scoping works. It isn't in scope where the body is defined. You have two good alternatives:
def run(f: Int => Unit) = f(1)
run { implicit i =>
todo // can use i here
}
Make run a macro. This should be at least an approximation (adapted from SI-5778), unfortunately I can't test it at the moment:
object Macros {
def run(f: => Unit) = macro runImpl
def runImpl(c : Context)(f: c.Tree) = q"""{
implicit val i: Int = 1
// some other implicits
$f
}"""
}

Scala bug? DelayedInit and Implicits

I've found extremely weird behaviour (scala 2.9.1 ) using and defining implicit values, and wondering if anyone can explain it, or if it's a scala bug?
I've created a self contained example:
object AnnoyingObjectForNoPurpose {
trait Printer[T] {
def doPrint(v: T): Unit
}
def print[T : Printer](v: T) = implicitly[Printer[T]].doPrint(v)
trait DelayedRunner extends DelayedInit {
def delayedInit(x: => Unit){ x }
}
// this works, as it should
object Normal extends DelayedRunner {
implicit val imp = new Printer[Int] {
def doPrint(v: Int) = println(v + " should work")
}
print(343)
}
// this compiles, but it shouldn't
// and won't run, cause the implicit is still null
object FalsePositive extends DelayedRunner {
print(123)
implicit val imp = new Printer[Int] {
def doPrint(v: Int) = println(v + " should not compile")
}
}
def main(args: Array[String]) {
implicit val imp = new Printer[Int] {
def doPrint(v: Int) = println(v + " should work")
}
print(44)
// print(33.0) // correctly doesn't work
Normal // force it to run
FalsePositive // force this to run too
}
}
Suppose you changed your definition of delayInit to be a no-op, i.e.
def delayedInit(x: => Unit) { }
Then in your main method do something like
println("FP.imp: " + FalsePositive.imp)
As expected that will print FP.imp: null, but the real point of the exercise is to illustrate that the block that defines the body of FalsePositive is acting like a regular class body, not a function body. It's defining public members when it sees val, not local variables.
If you added a method to AnnoyingObjectForNoPurpose like the following, it wouldn't compile because print's implicit requirement isn't satisfied.
def fails {
print(321)
implicit val cantSeeIt = new Printer[Int] {
def doPrint(v: Int) = println(v + " doesn't compile")
}
}
However if you defined a class along the same principle, it would compile, but fail at runtime when initialized, just like your FalsePositive example.
class Fine {
print(321)
implicit val willBeNull = new Printer[Int] {
def doPrint(v: Int) = println(v + " compiles, but fails")
}
}
To be clear, the compile behavior of Fine has nothing to do with the presence of the implicit. Class/object initializers are very happy to compile with val initializers which reference undefined vals.
object Boring {
val b = a
val a = 1
println("a=%s b=%s".format(a, b))
}
Boring compiles just fine and when it is referenced, it prints a=1 b=0
It seems like your question boils down to "Should the body of a class/object deriving from DelayedInit be compiled as if it's a class body or a function block?"
It looks like Odersky picked the former, but you're hoping for the latter.
That's the same bug as if I write this:
object Foo {
println(x)
val x = 5
}
It ain't a bug. Your constructor flows down the object body and happens in order. DelayedInit isn't the cause. This is why you need to be careful when using val/vars and ensure they init first. This is also why people use lazy val's to resolve initialization order issues.