I want to be able to define the following function in Scala:
import Numeric.Implicits._
def f[T:Numeric](a:T) = a*2
but I get the error
error: could not find implicit value for parameter num: scala.math.Numeric[Any]
def f[T:Numeric](a:T) = a*2
^
I can get it to work with an implicit n:Numeric[T] argument and n.fromInt, but readability suffers. (The real code I'm trying to write is more complicated than this.)
I tried to define an implicit conversion from Int to Numeric[T]:
implicit def intToNumericT[T](x:Int)(implicit n:Numeric[T]):T = n.fromInt(x)
but that doesn't help. Is there a way to get the above code to work?
You could pimp a multiply-by-int method onto numeric types:
import Numeric.Implicits._
implicit class RichNumeric[A](val a: A) extends AnyVal {
def *(i: Int)(implicit n: Numeric[A]) = n.times(a, n.fromInt(i))
}
def f[T: Numeric](a: T) = a * 2
How about:
implicit class NumericInt(x:Int){
def nu[T](implicit n: Numeric[T]) = n.fromInt(x)
}
import Numeric.Implicits._
def f[T: Numeric](a: T) = a * 2.nu
Example:
scala> def f[T: Numeric](a: T) = a * 2.nu
f: [T](a: T)(implicit evidence$1: Numeric[T])T
scala> f(5)
res0: Int = 10
I think that definition should be as follows:
import Numeric.Implicits._
def f[T <% Numeric[T]#Ops](a: T)(implicit f: Int => T) = a * 2
println(f(5)) // 10
println(f(BigDecimal(7))) // 14
println(f(1.7)) // 3.4
Related
I'm trying to write a function which re-uses the implicit conversions which I have for Object A -> Object B when they are wrapped in an Option in a generic way so that Option[A] -> Option[B] conversions also work.
What I've come up with is:
implicit def fromOptionToOption[A, B](from: Option[A])(implicit conversion: (A) => B): Option[B] = from.map(conversion(_))
This works when I assign a Some(..) to a value but not when I assign an Option val; see the following console output:
scala> trait T
defined trait T
scala> case class Foo(i: Int) extends T
defined class Foo
scala> case class Bar(i: Int) extends T
defined class Bar
scala> implicit def fromFooToBar(f: Foo):Bar = Bar(f.i)
fromFooToBar: (f: Foo)Bar
scala> implicit def fromBarToFoo(b: Bar):Foo = Foo(b.i)
fromBarToFoo: (b: Bar)Foo
scala> implicit def fromOptionToOption[A, B](from: Option[A])(implicit conversion: (A) => B): Option[B] = from.map(conversion(_))
fromOptionToOption: [A, B](from: Option[A])(implicit conversion: (A) => B)Option[B]
scala> val foo: Option[Foo] = Some(Bar(1))
foo: Option[Foo] = Some(Foo(1))
// THIS WORKS as expected
scala> val fooOpt = Some(Foo(4))
fooOpt: Some[Foo] = Some(Foo(4))
scala> val barOpt2: Option[Bar] = fooOpt
<console>:16: error: type mismatch;
found : Some[Foo]
required: Option[Bar]
val barOpt2: Option[Bar] = fooOpt
^
//THIS FAILS.
I don't really see the difference between the first and second conversion. Somehow it doesn't invoke the implicit conversion in the latter. I guess it has something to do with the type system, but I can't see how just yet. Any ideas?
-Albert
(I'm on scala 2.9.1)
Here's clue:
scala> val fooOpt: Option[Bar] = Option(Foo(1))
fooOpt: Option[Bar] = Some(Bar(1))
And another:
scala> implicit def foobar(x: String): Int = augmentString(x).toInt
foobar: (x: String)Int
scala> val y: Option[String] = Option(1)
y: Option[String] = Some(1)
scala> val y: Option[Int] = Option("1")
y: Option[Int] = Some(1)
Looks like a legitimately odd bug. I'd pop open a smaller test case and open an issue (or search for one in JIRA).
As an aside:
You could use some category theory to handle lots of different types of "Option-ish" things.
package object fun {
trait Functor[Container[_]] {
def fmap[A,B](x: Container[A], f: A => B): Container[B]
}
object Functor {
implicit object optionFunctor extends Functor[Option] {
override def fmap[A,B](x: Option[A], f: A => B): Option[B] = x map f
}
// Note: With some CanBuildFrom magic, we can support Traversables here.
}
implicit def liftConversion[F[_], A, B](x: F[A])(implicit f: A => B, functor: Functor[F]): F[B] =
functor.fmap(x,f)
}
That's a bit more advanced, as you're mapping some category theory FP onto the problem, but it's a more general solution to lift implicit conversations into containers as needed. Notice how they chain by using one implicit conversation method that takes a more limited implicit argument.
ALSO, this should make the examples work:
scala> val tmp = Option(Foo(1))
tmp: Option[Foo] = Some(Foo(1))
scala> val y: Option[Bar] = tmp
y: Option[Bar] = Some(Bar(1))
And make your usage of Some more dangerous:
scala> val tmp = Some(Foo(1))
tmp: Some[Foo] = Some(Foo(1))
scala> val y: Option[Bar] = tmp
<console>:25: error: could not find implicit value for parameter functor: fun.Functor[Some]
val y: Option[Bar] = tmp
^
That's telling you that variance is critical, and interacts with implicits. My guess is you ran into a very rare, probably hard to fix bug that can be avoided using other techniques.
You might not be aware of it, but there's a flag for that: -Xlog-implicits. And this is what it says:
scala> val barOpt2: Option[Bar] = fooOpt
fromOptionToOption is not a valid implicit value for Some[Foo] => Option[Bar] because:
incompatible: (from: Option[Foo])(implicit conversion: Foo => B)Option[B] does not match expected type Some[Foo] => Option[Bar]
<console>:16: error: type mismatch;
found : Some[Foo]
required: Option[Bar]
val barOpt2: Option[Bar] = fooOpt
^
And there you go -- it doesn't know what type B must be. 0__ mentioned that this problem doesn't happen with invariant collections, and that makes some sense. In invariant collections, B must be exactly Bar, while for covariant collections it could be any subtype of Bar.
So, why does val foo: Option[Foo] = Some(Bar(1)) work? Well, there's a flag for that too... -Ytyper-debug. Not for the weak, however, given the extreme verbosity.
I waddled through anyway, comparing what happens in both cases, and the answer is rather simple... it's not the Option that is being converted in that case, but Bar! Remember, you declared an implicit conversion from Bar => Foo, so it is applying that conversion before passing the result to Some!
It doesn't work because the Scala Language Specification defines view as follows:
Implicit parameters and methods can also define implicit conversions called views. A view from type S to type T is defined by an implicit value which has function type S=>T or (=>S)=>T or by a method convertible to a value of that type.
fromOptionToOption doesn't conform to the three categories since it takes an implicit parameter. Compiler doesn't seem to find converter with both destination and source having generic type.
Defining a view from Option[Foo] to Option[Bar] works as expected.
trait T
case class Foo(i: Int) extends T
case class Bar(i: Int) extends T
object Main {
implicit def fromFooToBar(f: Foo):Bar = Bar(f.i)
implicit def fromBarToFoo(b: Bar):Foo = Foo(b.i)
// implicit def fromOptionToOption[A, B](from: Option[A])(implicit conversion: (A) => B): Option[B] =
// from.map(conversion(_))
implicit def fromOptionFooToOptionBar(o: Option[Foo]): Option[Bar] = o map { foo => foo }
def test(): Option[Bar] = {
val fooOpt = Some(Foo(4))
val barOpt2: Option[Bar] = fooOpt
barOpt2
}
}
println(Main.test)
Running this prints out:
$ scala so.scala
Some(Bar(4))
However, all is not lost. It's not as nice as general Option to Option, but we can do something like anything that can turn into Bar to Option[Bar] by view bound.
trait T
case class Foo(i: Int) extends T
case class Bar(i: Int) extends T
object Main {
implicit def fromFooToBar(f: Foo):Bar = Bar(f.i)
implicit def fromBarToFoo(b: Bar):Foo = Foo(b.i)
implicit def fromOptionToOptionBar[A <% Bar](from: Option[A]): Option[Bar] =
from map { foo => foo }
def test(): Option[Bar] = {
val fooOpt = Some(Foo(4))
val barOpt2: Option[Bar] = fooOpt
barOpt2
}
}
println(Main.test)
Here's another workaround that can be used for general Option to Option but requires extra .convert call:
trait T
case class Foo(i: Int) extends T
case class Bar(i: Int) extends T
case class Converter[A](x: Option[A]) {
def convert[B](implicit ev: Function1[A, B]): Option[B] = x map { a: A => ev(a) }
}
object Main {
implicit def optionToConverter[A](x: Option[A]) = Converter(x)
implicit def fooToBar(x: Foo) = Bar(x.i)
def test(): Option[Bar] = {
val fooOpt = Some(Foo(4))
val barOpt: Option[Bar] = fooOpt.convert
barOpt
}
}
println(Main.test)
Indeed it's a very strange problem. I tried to use another type than Option, and it turns out that the problem is that Option is covariant in its type parameter. This works all:
case class A[B](value: B) // invariant in B
case class X()
case class Y()
implicit def xtoy(x: X): Y = Y()
implicit def ytox(x: Y): X = X()
implicit def movea[U, V](from: A[U])(implicit view: U => V): A[V] = A[V](from.value)
def test(a: A[Y]) = "ok"
test(A(X())) // (1)
val f = A(X())
test(f) // (2)
But if instead I define A as
case class A[+B](value: B) // covariant in B
The case (2) fails. Case (1) always succeeds, because Scala already converts X to Y before wrapping it in an A.
Now that we know the problem source, you need to wait for a type guru to explain why this is actually a problem... The conversion is still valid, you see:
askForY(movea(f)) // succeeds, even with A[+B]
I improved #jseureth answer and added support for Traversable:
trait Mappable[A, B, C[_]] {
def apply(f: A => B): C[B]
}
package object app {
implicit class OptionMappable[A, B, C[X] <: Option[X]](option: C[A]) extends Mappable[A, B, Option] {
override def apply(f: A => B): Option[B] = option.map(f)
}
implicit class TraversableMappable[A, B, C[X] <: Traversable[X]](traversable: C[A])
(implicit cbf: CanBuildFrom[C[A], B, C[B]]) extends Mappable[A, B, C] {
override def apply(f: A => B): C[B] = {
val builder = cbf(traversable)
builder.sizeHint(traversable)
builder ++= traversable.map(f)
builder.result()
}
}
implicit def liftConversion[C[_], A, B](x: C[A])
(implicit f: A => B, m: C[A] => Mappable[A, B, C]): C[B] = m(x)(f)
}
Now you can implicitly convert options and traversables:
implicit def f(i: Int): String = s"$i"
val a: Option[String] = Some(1)
val b: Seq[String] = Seq(1, 2, 3)
Is it possible to have syntax like (parameter1, parameter2) applied myFunction. Here myFunction would be applied to the given parameters. Concrete example: val myFunction = (a:String) => a+a+"there"; "hello" applied myFunction should output "hellohellothere".
I know it's possible to do (parameter1, parameter2) match {case myFunctionWrittenOut}, so the above would become "hello" match {case a:String => a+a+"there"} but here you have to write out the function: you can't use a reference.
I don't think it's possible with standard scala. But you can write some helper methods that would make something like this available:
implicit class Applied1[T](val t: T) extends AnyVal {
def applied[R](f: T => R): R = f(t)
}
implicit class Applied2[T1, T2](val t: (T1, T2)) extends AnyVal {
def applied[R](f: (T1, T2) => R): R = f(t._1, t._2)
}
implicit class Applied3[T1, T2, T3](val t: (T1, T2, T3)) extends AnyVal {
def applied[R](f: (T1, T2, T3) => R): R = f(t._1, t._2, t._3)
}
// ... and 19 more implicit classes: Applied4 to Applied22
And then you can use it like this:
def minus(a: Int): Int = -a
def plus(a: Int, b: Int): Int = a + b
def plus(a: Int, b: Int, c: Int): Int = a + b + c
scala> 5 applied minus
res0: Int = -5
scala> (1, 2) applied plus
res1: Int = 3
scala> (1, 2, 3) applied plus
res2: Int = 6
But this may be a bit more complex to use with generic functions, or functions with implicit arguments:
def mul[T : Numeric](a: T, b: T): T = {
import Numeric.Implicits._
a * b
}
scala> (1.5, 2.5) applied (mul(_, _))
res3: Double = 3.75
Implicit classes can be used to achieve something which which seems to be similar to what you are looking for.
An implicit class with only one constructor argument can be used as a pattern to add methods to the a given type. One example is DurationInt which "adds" methods to integers to enable converting them to durations. It is imported into scope using import scala.concurrent.duration._
A simplified version of DurationInt could be defined as follows:
implicit class DurationInt(n: Int) {
def seconds: FiniteDuration = Duration(n, TimeUnit.SECONDS)
}
This enables use of the seconds method on all integers
2.seconds // Returns a duration object
For functions with multiple arguments you can use a tuple argument for the implicit class:
implicit class TupleConcat(tuple: (String, String)) {
def concat: String = tuple._1 + tuple._2
}
// enables the following syntax
("aa", "bb").concat
It is common for implicit classes such as these to extend AnyVal, this allows some compiler optimizations which avoid actually having to instantiate the implicit class in many cases.
implicit final class DurationInt(val n: Int) extends AnyVal { /* implementation */ }
In Scala, the parameter list of a function is always written before the function:
val fn = (a: Int, b: Int) => a + b
// ^ parameters ^ ^ function
Suppose I'd like to traverse case class generic representation as described here
I've defined some typeclass to describe fields:
trait Described[X] extends (X => String)
object Described{
def apply[X](x: X)(implicit desc: Described[X]) = desc(x)
}
Defined some instance:
implicit object DoubleDescribed extends Described[Double]{
def apply(x: Double) = x.formatted("%01.3f")
}
And general user:
import shapeless._
import shapeless.labelled.FieldType
import shapeless.ops.hlist.LeftFolder
object DescrFolder extends Poly2{
implicit def field[X, S <: Symbol](implicit desc: Described[X],
witness: Witness.Aux[S]):
Case.Aux[Seq[String], FieldType[S, X], Seq[String]] =
at[Seq[String], FieldType[S, X]](
(descrs, value) => descrs :+ f"${witness.value.name}: ${desc(value)}")
}
def describe[T <: Product, Repr <: HList](struct: T)
(implicit lgen: LabelledGeneric.Aux[T,Repr],
folder: LeftFolder.Aux[Repr, Seq[String], DescrFolder.type, Seq[String]]
): String = {
val repr = lgen.to(struct)
val descrs = folder(repr,Vector())
descrs.mkString(struct.productPrefix + "{", ",", "}")
}
So now i could write
case class Point(x: Double, y: Double, z: Double)
describe(Point(1,2,3.0))
and get
res1: String = Point{x: 1,000,y: 2,000,z: 3,000}
Now i'd like to define some field metadata using shapeless tags:
import tag._
trait Invisible
val invisible = tag[Invisible]
implicit def invisibleDescribed[X](implicit desc: Described[X])
: Described[X ## Invisible] =
new Described[X ## Invisible]{
def apply(x: X ## Invisible) = desc(x: X) + "[invisible]"
}
so Described(invisible(0.5)) now succesfully produces
res2: String = 0,500[invisible]
But with redefined
case class Point(x: Double, y: Double, z: Double ## Invisible)
describe(Point(1,2,invisible(3.0)))
yields compilation error:
Error: diverging implicit expansion for type
LeftFolder.Aux[this.Out,Seq[String],DescrFolder.type,Seq[String]]
starting with method invisibleDescribed in class ...
I presume that type X with Tag[Y] with KeyTag[K,X] is not identifying as FieldType[S, X] but could not guess how to fix it.
How could one define proper LeftFolder for such situation?
Your issue does not involve shapeless at all. It can be actually simplified as:
trait Described[T]
trait Invisible
implicit val doubleDescribed: Described[Double] = ???
implicit def invisibleDescribed[T](
implicit desc: Described[T]
): Described[T with Invisible] = ???
implicitly[Described[Double with Invisible]]
Double ## Invisible can be "represented" as Double with Invisible. Note that Double with Invisible <: Double.
When the compiler tries to get an implicit Described[Double with Invisible] it correctly complains about diverging implicit expansion: doubleDescribed and invisibleDescribed.
Going back to your original code, an easy fix could be to just rewrite invisibleDescribed as:
implicit def invisibleDescribed[X, I <: X ## Invisible](
implicit desc: Described[X]
): Described[I] = new Described[I]{
def apply(x: I) = desc(x: X) + "[invisible]"
}
Given the following Addable type-class:
scala> trait Addable[A] {
| def add(x: A): A
| }
defined trait Addable
I created an instance for Int:
scala> class AddInt(x: Int) extends Addable[Int] {
| override def add(y: Int) = x + y
| }
defined class AddInt
Then, I created an implicit AddInt:
scala> implicit val addInt: AddInt = new AddInt(10)
addInt: AddInt = AddInt#1f010bf0
Lastly, I defined a generic function, foo:
scala> def foo[A](x: A)(implicit ev: Addable[A]): A = ev.add(x)
foo: [A](x: A)(implicit ev: Addable[A])A
Now, I can call it with the successful implicit resolution of addInt:
scala> foo(10)
res0: Int = 20
How can I define foo using the context bound notation?
example:
def foo[A : Addable]...?
Just define the method like you do in your own example:
def foo[A : Addable](x: A) = implicitly[Addable[A]].add(x)
Consider the following (working) snippet that defines bidirectional implicit conversions between the DenseVector and Arrays:
import scala.reflect.ClassTag
import org.apache.spark.mllib.linalg.Vectors
import breeze.linalg.{DenseVector => BDV}
implicit def bdvToSeq[T](vect: BDV[T])(implicit ct: ClassTag[T]): Seq[T] = vect.toArray.toSeq
implicit def arrayToVect(darr: Array[Double]): BDV[Double]
= new BDV(darr)
implicit def bdvToArray[T](vect: BDV[T])(implicit ct: ClassTag[T]): Array[T] = vect.toArray
def add(v1: BDV[Double], v2: BDV[Double]) =
v1.zip(v2).map { x => x._1 + x._2}
Let's try it out:
scala> arr.allVisitableIndicesActive // Array to DenseVector implicit conversion
res4: Boolean = true
scala> val d = new BDV(Array(77.7, 88.8, 99.9))
d: breeze.linalg.DenseVector[Double] = DenseVector(77.7, 88.8, 99.9)
Now the other direction:
scala> def myArrMethod(arr: Array[Double]) = println(arr.mkString(","))
myArrMethod: (arr: Array[Double])Unit
scala> myArrMethod(d) // DenseVector to array conversion
77.7,88.8,99.9
The following also works: notice the darr.toSeq
def norm(darr: Array[Double]): Double = {
Math.sqrt(darr.toSeq.foldLeft(0.0) { case (sum, dval) => sum + Math.pow(dval, 2)})
}
However if we omit the .toSeq then we have implicits collision:
scala> def norm(darr: Array[Double]): Double = {
Math.sqrt(darr.foldLeft(0.0) { case (sum, dval) => sum + Math.pow(dval, 2)})
}
<console>:34: error: type mismatch;
found : darr.type (with underlying type Array[Double])
required: ?{def foldLeft(x$1: ? >: Double(0.0)): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method doubleArrayOps in object Predef of type (xs: Array[Double])scala.collection.mutable.ArrayOps[Double]
and method arrayToVect of type (darr: Array[Double])breeze.linalg.DenseVector[Double]
are possible conversion functions from darr.type to ?{def foldLeft(x$1: ? >: Double(0.0)): ?}
Math.sqrt(darr.foldLeft(0.0) { case (sum, dval) => sum + Math.pow(dval, 2)})
^
<console>:34: error: value foldLeft is not a member of Array[Double]
Math.sqrt(darr.foldLeft(0.0) { case (sum, dval) => sum + Math.pow(dval, 2)})
I would however prefer not to put the ".toSeq" explicitly.
So my question is: how to set the proper precedence so that the Predef.toSeq is the clear winner - always tried before the custom lower priority implicits defined above?
You can extract all your implicit conversions into object, and import them only where needed
trait BDVImplicits {
implicit def bdvToSeq[T](vect: BDV[T])(implicit ct: ClassTag[T]): Seq[T] =
vect.toArray.toSeq
implicit def arrayToVect(darr: Array[Double]): BDV[Double] =
new BDV(darr)
implicit def bdvToArray[T](vect: BDV[T])(implicit ct: ClassTag[T]): Array[T] =
vect.toArray
}
object BDVImplicits extends BDVImplicits
If you'll place your 'norm' method in Utils for example, and don't import implicit you'll be good. You'll just need to import BDVImplicits._ in class where you call your Util methods.
I think it's simplest workaround for this problem.