Could not find implicit value for parameter - scala

I've recently started learning Scala's implicit "magic" and I'm having troubles with implicit Scala objects. I've tried all the possible variants but nothing seems to work.
Lets assume I have a class like this with some solve() function. It should return 2 Float values if the input a, b were Float. Otherwise it should return another type values:
class Solver[T](val a: T, val b: T) {
def solve[A](implicit num: customNumeric[T]): Option[(T, T)] = {
Option(
num.f(num.g(a)),
num.f(num.g(b)))
}
}
Let's assume another-type-value is an object of class like this:
class MyClass[T] (x: T, y: T)(implicit num: customNumeric[T]) {
val field : T = num.f(x)
}
And let's also assume that I dont have the functions I need in basic Scala Numeric so I should make my own custom numeric.
Here is what I've done:
I've made an abstract class for my own customNumeric with my methods f() and g() and couple of implicit objects that extend my customNumeric for some value types (Int, Float for example) and implemented method in them:
abstract class customNumeric[T] {
def f(x: T): T
def g(x: T): T
}
object customNumeric {
implicit object IntIsCustomNumeric extends customNumeric[MyClass[Int]] {
def f(x: MyClass[Int]) = new MyClass[Int](x.field + 5)
def g(x: MyClass[Int]) = new MyClass[Int](x.field - 5)
}
implicit object FloatIsCustomNumeric extends customNumeric[Float] {
def f(x: Float): Float = x + 3
def g(x: Float): Float = x - 3
}
}
In my opinion Solver's solve() should use implicit customNumeric object to get implementations for methods referenced inside solve() based upon type of the Solver's input values.
But this doesn't work as compiler says:
could not find implicit value for parameter num: customNumeric[Int]
def f...
It also complains because of not enough arguments for constructor MyClass at the same line.
I've already tried making companion object to cast Int to MyClass:
object Fraction {
implicit def int2MyClass(x: Int): MyClass[Int] = new MyClass[Int](x, 1)
}
But that also doen't seem to work. And I've tried to make another implicit object to implement methods I use in customNumeric[MyClass[Int]].
Do you have any ideas? Thanks in advance!

The problem is that you're trying to define the implicit objects with classes that themselves require that same implicit object.
Meaning, this:
class MyClass[T] (x: T, y: T)(implicit num: CustomNumeric[T])
Requires an existence of an implicit CustomNumeric[T]. You cannot define IntIsCustomNumeric using that type:
implicit object IntIsCustomNumeric extends customNumeric[MyClass[Int]]
When you implement IntIsCustomNumeric, you need to implement it for type Int, not for type MyClass[Int]. When you do that, i.e:
object CustomNumeric {
implicit object IntIsCustomNumeric extends CustomNumeric[Int] {
override def f(x: Int): Int = x
override def g(x: Int): Int = x
}
}
Now, you can create an Solver[Int] which takes an implicit CustomNumeric[Int]:
def main(args: Array[String]): Unit = {
import CustomNumeric._
val solver = new Solver[Int](1, 2)
println(solver.solve)
}
Now, it's also easier to create an implicit conversion from an Int type to something that creates a MyClass[Int]:
implicit object MyClassIsCustomNumeric extends CustomNumeric[MyClass[Int]] {
override def f(x: MyClass[Int]): MyClass[Int] = new MyClass[Int](x.field + 5)
override def g(x: MyClass[Int]): MyClass[Int] = new MyClass[Int](x.field + 3)
}
implicit def intToMyClass(i: Int) = new MyClass[Int](i)

What do you think about this
object customNumeric {
implicit object IntIsCustomNumeric extends customNumeric[Int] {
def f(x: Int): Int = x + 3
def g(x: Int): Int = x - 3
}
implicit object FloatIsCustomNumeric extends customNumeric[Float] {
def f(x: Float): Float = x + 3
def g(x: Float): Float = x - 3
}
implicit def int2MyClass(x: Int): MyClass[Int] = new MyClass[Int](x, 1)
implicit object cn extends customNumeric[MyClass[Int]] {
def f(x: MyClass[Int]) = x.field + 5
def g(x: MyClass[Int]) = x.field - 5
}
}

Related

How does scala handle implicit typeclasses without instantiating a member?

I notice when I'm trying to create an instance of a fooSemigroup, in version one the anonymous function creates an instance of fooSemigroup without instantiating a member of Foo, but when I try to do this without the SAM construct, I need to create a dummy instance of foo for the SemigroupOps to pull in the implicit value ev.
trait Semigroup[A] {
def combine(x: A, y: A): A
}
case class Foo(v: Int)
// vs 1
implicit val fooSemigroup: Semigroup[Foo] = (x: Foo, y: Foo) => Foo(x.v + y.v)
// vs 2
class fooSemigroup(foo: Foo) extends Semigroup[Foo] {
def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}
implicit val f: fooSemigroup = Foo(0)
implicit class SemigroupOps[A](x: A) {
def +(y: A)(implicit ev: Semigroup[A]): A = ev.combine(x, y)
}
Instead of implicit class
implicit class fooSemigroup(foo: Foo) extends Semigroup[Foo] {
def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}
try implicit object
implicit object fooSemigroup extends Semigroup[Foo] {
def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}
However as per Luis' advice favour implicit val instances over implicit object as otherwise resolution might result in ambiguous implicit values error, for example
trait SomeTrait[T] {
def f: T
}
trait ExtendedTrait[T] extends SomeTrait[T] {
def g: T
}
implicit object SomeStringObject extends SomeTrait[String] {
override def f: String = "from object f"
}
implicit object ExtendedStringObject extends ExtendedTrait[String] {
override def f: String = "from extended obj f"
override def g: String = "from extended obj g"
}
implicitly[SomeTrait[String]] // Error: ambiguous implicit values
where full error states
Error:(15, 77) ambiguous implicit values:
both object ExtendedStringObject in class A$A7 of type A$A7.this.ExtendedStringObject.type
and object SomeStringObject in class A$A7 of type A$A7.this.SomeStringObject.type
match expected type A$A7.this.SomeTrait[String]
def get$$instance$$res0 = /* ###worksheet### generated $$end$$ */ implicitly[SomeTrait[String]];}
^

Scala Subclass change return type without override

Let's say I have a class called A:
class A(i: Int) {
//private def to initialize a calculated value
def maintainedValue : Int = calculatedValue
def double : A = new A(maintainedValue * 2)
def combine(other: A) : A = new A(maintainedValue + other.maintainedValue)
def addAmt(amt : Int) : A = new A(maintainedValue + amt)
// Many many more methods
}
I want to define a class B that extends class A such that it's methods, almost all of which have similar logic, return an object of class B:
class B(i: Int) extends A(i) {
//private def to initialize a differently calculated value
def maintainedValue : Int = diffCalculatedValue
//Change all other methods to return type B without override???
}
Is it possible to do this without overriding all the methods?
Is there a simple way to instantiate these new instances with a variable/dynamic class?
Perhaps there is a more elegant way to do this?
One solution, and the simplest one in my opinion, is to change class A to have a structure such that a single method handles object creation:
def create(i: Int): TYPE = new B(i)
And just use an implicit method in class B to handle casting when calling the unaltered methods:
private implicit def convert(a: A): B = new B(a.maintainedValue)
Short and sweet, though I'm curious how efficient and/or scale-able this solution is.
How about having base trait with common logic and two implementation?
object App extends App {
println(A(1).double)
println(B(1).double)
}
trait A {
type TYPE
def create(i: Int): TYPE
def maintainedValue: Int
def double: TYPE = create(maintainedValue * 2)
def addAmt(amt: Int): TYPE = create(maintainedValue + amt)
}
trait B extends A {
}
object A {
def apply(i: Int) = new AImpl(i)
case class AImpl(i: Int) extends A {
override type TYPE = A
override def create(i: Int) = A(i)
override def maintainedValue: Int = 2
}
}
object B {
def apply(i: Int): B = new BImpl(i)
case class BImpl(i: Int) extends B {
override type TYPE = B
override def create(i: Int): TYPE = B(i)
override def maintainedValue: Int = 1
}
}

Abstracting out function across value classes

Let's say I have the following code for value classes:
class Meters(val x: Int) extends AnyVal {
def +(m: Meters): Meters = new Meters(x + m.x)
}
class Seconds(val x: Int) extends AnyVal {
def +(s: Seconds): Seconds = new Seconds(x + s.x)
}
Is there any way for me to remove duplication of the "+" methods?
Something kind of like:
abstract class Units[T <: Units[T]](val x: Int) extends AnyVal {
def +(other: T): T = T(x + other.x)
}
Except I can't inherit from value classes, and I definitely can't use T like a constructor.
You can use a universal trait with a type class, lets start defining the trait.
trait Sum[T <: Sum[T]] extends Any {
val x: Int
def +(other: T)(implicit evidence : FromInt[T]): T = evidence.fromInt(x + other.x)
}
Now we need a type class that tell us how to go from an integer to some type, lets define this and call it FromInt
trait FromInt[T] {
def fromInt(x: Int) : T
}
now lets define the Meters value class which is as simple as
class Meters(val x :Int) extends AnyVal with Sum[Meters]
and in the companion object we can provide an implicit value of the type class we defined.
object Meters{
implicit val intConstructable : FromInt[Meters] = new FromInt[Meters] {
override def fromInt(x: Int) = new Meters(x)
}
}
and now we can just do
val added = new Meters(2) + new Meters(3)
println(added.x)

List of elements implementing typeclass A and B in Scala

I got the following issue when trying to use typeclasses throughout my project.
trait FooAble[T] { def fa(t: T): List[T] }
object Foo { def apply[T](t: T) = implicitly[FooAble[T]].fa(t) }
trait BarAble[T] { def fb(t: T): Double }
object Bar { def apply[T](t: T) = implicitly[BarAble[T]].fb(t) }
And would like to be able to do the following:
// xs contains elements of type A and B which are subclasses of the trait Something
def f(xs: List[Something]) = {
val something = xs.map(Foo)
val somethingElse = xs.map(Bar)
}
However, this would not work as we don't know if Something implements A[]and B[], no implicit implementation found. What do I need to do so that the elements of the list xs implement the typeclasses FooAble and BarAble?
I think this question: What are type classes in Scala useful for? will help you to understand the proper use (& usefulness) of type classes.
Am just extending the answer by Kevin Wright in the above link for your use case (if I understand your need correctly!):
trait Addable[T] {
def zero: T
def append(a: T, b: T): T
}
trait Productable[T] {
def zero: T
def product(a: T, b: T): T
}
implicit object IntIsAddable extends Addable[Int] {
def zero = 0
def append(a: Int, b: Int) = a + b
}
implicit object IntIsProductable extends Productable[Int] {
def zero = 1
def product(a: Int, b: Int) = a*b
}
def sumAndProduct[T](xs: List[T])(implicit addable: Addable[T], productable: Productable[T]) =
(xs.foldLeft(addable.zero)(addable.append), xs.foldLeft(productable.zero)(productable.product))
So akin to above, in your use case, you need to provide implicit objects which implement your type classes FooAble & BarAble and your method signature for function f becomes:
def f[Something](xs: List[Something])(implicit fooable: FooAble[Something], barable: BarAble[Something])

Scala generic implicit values ambiguous when overloading?

The following outputs 0 instead of my desired result, which is 2.
This looks similar to this question, but here I am using parentheses everywhere.
object Test {
implicit def x = List(1, 2)
trait A[T] {
def res(): Int = 0
def makeResPlusOne(): Int = res() + 1 // All right
}
trait B[T] extends A[T] {
def res()(implicit y: List[T]) = y.size
}
class AA extends A[Int]
class BB extends B[Int]
}
val x: Test.A[Int] = new Test.BB
x.res() // Outputs 0 instead of 2.
I would like the last result to be obviously 2, the size of y, but it outputs 0.
If I add the keyword override to the method in B[T], it says that it overrides nothing.
If I add the implicit argument to the method res in A[T] like that ...
object Test {
implicit def x = List(1, 2)
trait A[T] {
def res()(implicit y: List[T]): Int = 0 // Added the implicit keyword.
def makeResPlusOne(): Int = res() + 1 // Fails to compile.
}
trait B[T] extends A[T] {
override def res()(implicit y: List[T]) = y.size
}
class AA extends A[Int]
class BB extends B[Int]
}
val x: Test.A[Int] = new Test.BB
x.res() // Error
... it raises the following error:
error: could not find implicit value for parameter y: List[Int]
What am I doing wrong ? How can I get the benefits of implicit values in subclasses and still being able to overload super methods ?
EDIT
It works if I import an implicit. However, I have the method makeResPlusOne(), which triggers the error in the second case, but not in the first. Please tell me how to properly define this method, which normally does not need an implicit at compile time.
_
error: could not find implicit value for parameter y: List[T]
def makeResPlusOne(): Int = res() + 1
^
You were close:
object Test {
implicit def list = List(1, 2)
trait A[T] {
def res()(implicit y: List[T]): Int = 0 // Added the implicit keyword.
}
trait B[T] extends A[T] {
override def res()(implicit y: List[T]) = y.size
}
class AA extends A[Int]
class BB extends B[Int]
}
import Test.list
val x: Test.A[Int] = new Test.BB
x.res() // Works!
You forgot to import the implicit list. Note that I have renamed the implicit to avoid conflict when importing with the variable x.
EDIT:
If you want def makeResPlusOne()(implicit y: List[T]): Int = res() + 1 you need to have an implicit List[T] in the scope, so you must add (implicit y: List[T]) as well.
object Test {
implicit def xx = List(1, 2)
trait A[T] {
def res()(implicit y: List[T]): Int = 0
def makeResPlusOne()(implicit y: List[T]): Int = res() + 1 // Works now.
}
trait B[T] extends A[T] {
override def res()(implicit y: List[T]) = y.size
}
class AA extends A[Int]
class BB extends B[Int]
}
import Test.xx // import the implicit list
val x: Test.A[Int] = new Test.BB
x.res() // Works
This code works fine for me (notice I changed your implicit from a def to a val):
object Test {
implicit val xx = List(1, 2)
trait A[T] {
def res()(implicit y: List[T]): Int = 0 // Added the implicit keyword.
}
trait B[T] extends A[T] {
override def res()(implicit y: List[T]) = y.size
}
class AA extends A[Int]
class BB extends B[Int]
val x: Test.A[Int] = new Test.BB
x.res()
}
Not sure if this still meets your needs with the changes though. The underlying issue really was that, as the compiler was telling you, you did not have an implicit List[Int] in scope. My example moved the x.res() call into the Test object therefore bringing it into scope, but you could also have just imported the existing implicit into scope as mentioned by #Stephane Godbillon.