with Cats, I can write this simple program
def foo(x: Int) = x + 1
val bar = Functor[Future](foo)
and Now I can do a bar(future(1)) and get a Future.Success(2) as a result. Very good.
But suppose my function was
def foo[T](x: T)(implicit m: Manifest[T]) : String = {...}
Now if I try to lift this function
def futureFoo = Functor[Future].lift(foo)
I get a compiler error No Manifest available for T.
So how do I lift this function?
I searched and found this thread (which is for scalaz)
Lifting a function which takes implicit parameter using functor (Scalaz7)
But I still couldn't create anything which worked for me. I tried
val futureFoo = Functor[T].lift2(foo[T] _)
but this doesn't compile
Functions in Scala cannot have implicit parameters, so when you try to eta-expand a method with an implicit parameter into a function, the implicit needs to be resolved before the function itself is applied. That is, at the time of eta-expansion. The compiler doesn't have a generic Manifest[T] in scope, but futureFoo can require one.
def foo[T](x: T)(implicit m: Manifest[T]) : String = ""
scala> def optionFoo[T: Manifest] = Functor[Option].lift(foo[T] _)
optionFoo: [T](implicit evidence$1: Manifest[T])Option[T] => Option[String]
I used Option because I didn't have a Functor[Future] readily available, the the same concept applies. Note that in order to use this, you'll need to supply the type parameter manually for it to return the correct function.
scala> optionFoo[Int].apply(Option(1))
res2: Option[String] = Some()
Related
I have not defined the function ev anywhere. Then, how come the below code works? Don't implicits have to be defined somewhere in scope for them to be used?
def same[T, U](x: U)(implicit ev: U => T): T = {ev(x)}
same(2) // 2
Any time you have questions like this, a good place to start is by using the Scala reflection API in the REPL to ask the compiler what's going on:
scala> import scala.reflect.runtime.universe.{ reify, showCode }
import scala.reflect.runtime.universe.{reify, showCode}
scala> def same[T, U](x: U)(implicit ev: U => T): T = ev(x)
same: [T, U](x: U)(implicit ev: U => T)T
scala> showCode(reify(same(2)).tree)
res0: String = $read.same(2)(Predef.$conforms)
So ev is provided by Predef.$conforms, an implicit method that will give you an instance of A <:< A for any A, where <:< extends Function1.
So that's one clue. Figuring out the rest requires thinking a little about type inference. When you call same(2), the compiler figures out that the expression 2 has type Int, and infers that U is Int. Next it needs to figure out what T is, and to do that it goes looking for implicit functions from Int to x for some type x.
This is where $conforms comes in. It's the only such method in scope, so the compiler chooses it, which means that ev is of type Int => Int and T has to be Int, and you're done.
Given a made-up F type-class:
scala> trait F[A] {}
defined trait F
and this definition, which uses a context bound to require that the input A has a type-class instance of F:
scala> def f[A : F](x: A) = ???
f: [A](x: A)(implicit evidence$1: F[A])Nothing
I defined a Person and type-class instance:
scala> case class Person(name: String)
defined class Person
scala> implicit val person: F[Person] = new F[Person] {}
person: F[Person] = $anon$1#262b2c86
And the following compiles:
scala> f(Person("foo"))
scala.NotImplementedError: an implementation is missing
But, there's no String implementation, so it fails.
scala> f("foobar")
<console>:17: error: could not find implicit value for evidence parameter of type F[String]
f("foobar")
^
I then defined an F[String] using:
scala> implicit def fInstance(x: String) = new F[String] {}
fInstance: (x: String)F[String]
But, I can't run:
scala> f("foobar")
<console>:18: error: could not find implicit value for evidence parameter of type F[String]
f("foobar")
^
since I do not have an implicit F[String], but rather a String => F[String].
What's the proper way to use such an implicit def to meet the F[String] constraint, i.e. call the f function successfully with a type of String?
I got it to work via:
scala> implicit val x: F[String] = implicitly[String => F[String]].apply("foobar")
x: F[String] = $anon$1#7b7fdc8
scala> f("foobar")
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
at .f(<console>:12)
... 33 elided
But I'm not sure if it's the right/clean way to do it.
You defined an implicit conversion. If you want to use a def to provide typeclass instances you just write the same as you'd write an implicit val but replace val with def.
implicit def fInstance = new F[String] {}
Normally you only use a def if you need type parameters, like here.
implicit def fInstance[A] = new F[List[A]] {}
Or
implicit def fInstance[A](implicit ev: F[A]) = new F[List[A]] {}
Your fInstance defines an implicit conversion, i.e. a way to turn a String into F[String]. For generating a typeclass instance, a method accepting implicit parameters can be used:
implicit def fInstance(implicit x: String) = new F[String] {}
it is typically used in FP libraries to derive one typeclass from another:
implicit def optionMonoid[A](implicit S: Semigroup[A]): Monoid[Option[A]] = ???
// or, which is the same
// implicit def optionMonoid[A: Semigroup]: Monoid[Option[A]] = ???
The idea is that F[String] can operate on any String in general, not being dependent on actual arguments provided into function. Of course, you can always provide instances explicitly:
f("foobar")(new F[String] { })
As a follow-up, the important part of typeclasses is that you can define them ad-hoc, i.e. not having access to definitions of F and String at all, and you are forced to scope implicits in Scala and import them, so it's totally ok.
Here is a simpler version of your definition (and you can remove implicit from fInstance):
implicit val singleFInstance: F[String] = fInstance("") // or fInstance("foobar"), etc.
Whether this is the right thing to do, very much depends on what F and f are supposed to mean.
But generally speaking: if F is really a type-class, fInstance(string) gives different results depending on the string (not just different instances, but different behavior), and f's signature is correct, then this is wrong and you should accept that calling f("foobar") isn't meaningful.
I've got a function create is going to provide the parameter DSLContext of op: DSLContext => T :
def create[T](op: DSLContext => T)(implicit errorHandler: Throwable => Unit):Option[T] = {
...
op(new DSLContext)
...
}
Then I pass the following function to create:
def query(implicit dsl:DSLContext)
And here is the call
create(query)
I got this compiler error:
could not find implicit value for parameter dsl: org.jooq.DSLContext
[error] create (query)
I can resolve this issue this way : create {implicit dsl => query}
However i wonder why is the compiler unable to resolve the implicit parameter dsl as a given parameter ?
The issue here is that when you pass a method where a function is expected the compiler needs to perform an eta-expansion to convert it.
In other words the method query needs to become a Function1[DSLContext, T].
However, the compiler needs to resolve the implicit parameter in order to be able to apply the eta-expansion. In your case there's no DSLContext in scope, so the compiler fails in doing so.
You can reproduce this behavior with a simpler example, here's a REPL session demonstrating it:
scala> def foo(implicit i: Int) = "hello"
foo: (implicit i: Int)String
scala> foo _
<console>:10: error: could not find implicit value for parameter i: Int
foo _
^
scala> implicit val x = 5
x: Int = 5
scala> foo _
res3: scala.collection.immutable.WrappedString = hello
where _ manually triggers the eta-expansion.
For the record, this is described in the language reference, paragraph 6.26.2.
If the method takes only implicit parameters, implicit arguments are passed following the rules of ยง7.2.
How would one encode the following constraint in Scala (pseudocode)?
def foo(x: T forSome { type T has a Numeric[T] instance in scope }) = {
val n= implicitly[...] // obtain the Numeric instance for x
n.negate(x) // and use it with x
}
In words: I need a type class instance for my input argument, but I don't care about the argument's type, I just need to obtain the instance and use it on my argument.
It doesn't have to be an existential type, but I need to avoid type parameters in the def's signature.
Edit: just to clarify, the standard approach in these cases, i.e.:
def foo[T: Numeric](x: T) = ...
doesn't work for me, as it requires the addition of a type parameter on the method.
Thanks.
I managed to make it work like this:
implicit class InstanceWithNumeric[T](val inst: T)(implicit val n: Numeric[T])
def foo(iwn: InstanceWithNumeric[_]) {
def genFoo[T](iwn: InstanceWithNumeric[T]) {
println(iwn.n.negate(iwn.inst))
}
genFoo(iwn)
}
And now:
scala> foo(1)
-1
scala> foo(1.2)
-1.2
Not the prettiest, but seems to work.
EDIT: You can avoid defining inner function like this:
implicit class InstanceWithNumeric[T](val inst: T)(implicit val n: Numeric[T]) {
def negate = n.negate(inst)
}
Also, if you want to make implicit conversion to InstanceWithNumeric globally visible, you can do something like this:
class InstanceWithNumeric[T](val inst: T)(implicit val n: Numeric[T])
object InstanceWithNumeric {
implicit def apply[T: Numeric](inst: T) =
new InstanceWithNumeric(inst)
}
If you want to understand how this works, read about so called implicit scope (this question seems to contain good explanation).
Not quite sure what you are attempting, because it seems you need a type once you make the call to implicitly. Would the following work for you?
def foo(implicit x: Numeric[_]) {
//code goes here.
}
I have the following use case which occurs often in my code:
A Collection[A]
An implicit conversion A to B
and I want to obtain a collection of B. I can use implicitly like the following:
case class Items(underlying:List[B])
import B._
def apply(a:List[A]):Items = {
val listOfB= a.map {implicitly[A=>B]}
Items(listOfB)
}
What is the most elegant way to do that in Scala, maybe with the help of Scalaz of doing the same?
Edit: the goal of my question is to find an idiomatic way, a common approach among libraries/developers. In such a sense developing my own pimp-my-library solution is something I dislike, because other people writing my code would not know the existence of this conversion and would not use it, and they will rewrite their own. I favour using a library approach for this common functions and that's why I am wondering whether in Scalaz it exists such a feature.
It's pretty straightforward if you know the types. First implicit conversion from A to B:
implicit def conversion(a: A): B = //...
then you need implicit conversion from List[S] to List[T] where S and T are arbitrary types for which implicit conversion from S to T exists:
implicit def convList[S, T](input: List[S])(implicit c: S => T): List[T] =
input map c
This should then work:
val listOfA: List[A] = //...
val listOfB: List[B] = listOfA
which is resolved by the compiler to:
val listOfB: List[B] = convList(listOfA)(conversion)
where S is A and T is B.
I wouldn't use an implicit conversion here, but a view bound in the class:
case class Foo(x: Int)
case class Bar(y: Int)
implicit def foo2Bar(foo: Foo) = Bar(foo.x)
case class Items[A <% Bar](xs: List[A]) {
def apply(x: Int): Bar = xs(x)
}
You can now create an instance of Items with a list of Foo and internally use them, as if they were Bars.
scala> Items(List(Foo(1)))
res8: Items[Foo] = Items(List(Foo(1)))
scala> res8(0)
res9: Bar = Bar(1)
edit:
Some clarification, on why I would not use an implicit conversion:
Implicit conversions can be dangerous, when they are in scope and accidentally convert things, that they shouldn't convert. I would always convert stuff explicitly or via view bounds, because then I can control it, also implicit conversion may shrink the size of your code, but also makes it harder to understand for others. I would only use implicit conversion for the 'extend my library' pattern.
edit2:
You could however add a method to the collection types, that does this conversion, if such a method is in scope:
trait Convertable[M[A], A] {
def convertTo[B](implicit f: A => B): M[B]
}
implicit def list2Convertable[A](xs: List[A]) = new Convertable[List, A] {
def convertTo[B](implicit f: A => B) = xs.map(f)
}
scala> implicit def int2String(x: Int) = x.toString
int2String: (x: Int)String
scala> List(1,2,3).convertTo[String]
res0: List[String] = List(1, 2, 3)
Instead of using another implicit conversion here, I would probably use a typeclass instead, but I think you get the basic idea.
Works starting with Scala 2.10:
implicit class ListOf[A](val list: List[A]) {
def of[B](implicit f: A => B): List[B] = list map f
}
implicit def int2String(i: Int) = i.toString
// Usage
List(1,2,3).of[String]
In my code, I'm using a more general version adapted from Tomasz' solution above which handles all Traversable instances
/** Implicit conversion for Traversable instances where the elements are convertable */
implicit def convTrav[S, T, I[S] <: Traversable[S]](input: I[S])(implicit c: S => T): I[T] =
(input map c).asInstanceOf[I[T]]
(This is working for me, although I'm keen to know if any more experienced Scala programmers think this is a bad idea for any reason, apart from the usual caveats about implicit conversions)