I would like to know if it is possible to use both an implicit
class and implicit conversion together. In the example below
I would like to call an operator on a tuple but have that tuple
first be converted to an anonymous class.
Unfortunately I get:
value andNext is not a member of (String, Int => Int)
Anyone know how to get this working (or confirm that it is not possible).
Unfortunately I cannot get it to work on 2.12.6. I have also tried
2.11.x and 2.12.x in Scastie but compilation fails with these errors:
value -: is not a member of (String, Int => Double)
value andNext is not a member of (String, Int => Int)
In Dotty this works without a problem. Initially I thought
this may be due to the left/right associativity but both
methods seem to fail.
Can anyone give me ideas on how to get implicit
conversion working in this example?
TIA.
PS: The initial code was not correct in several places (due to right
associativity of the operator), so I now use this code for testing:
object Test {
import scala.language.implicitConversions
trait NamedFunc[I,O]{
def name:String
def func(i:I): O
}
implicit def toNamedFunc[I,O](named_func: (String, I => O)): NamedFunc[I,O] = {
val nm = named_func._1
val f = named_func._2
new NamedFunc[I,O] {
override val name: String = nm
override def func(b:I): O = {
f(b)
}
}
}
implicit class FuncOps[T,IO,O](t: T)(implicit conv: T => NamedFunc[IO,O]) {
private val o = conv(t)
def -:[I](that: NamedFunc[I,IO]): NamedFunc[I,O] = {
new NamedFunc[I,O] {
override val name: String = that.name + " ->: " + o.name
override def func(b:I): O = {
val first:IO = that.func(b)
o.func(first)
}
}
}
def andNext[I](that: NamedFunc[O,I]): NamedFunc[IO,I] = {
new NamedFunc[IO,I] {
override val name: String = o.name + " andNext " + that.name
override def func(b:IO): I = {
val first:O = o.func(b)
that.func(first)
}
}
}
}
def f(a:Int):Int = -a
val h: Int => Double = (a:Int) => (2*a).toDouble
def main(args: Array[String]): Unit = {
val n1:NamedFunc[Int,Int] = ("f", f _)
val n2:NamedFunc[Int,Double] = ("h", h)
// n2 is assigned implicit class member t (right associative)
val itn1_2 = n1 -: n2
println(itn1_2.name)
println(itn1_2.func(2))
// ("h", h) is assigned implicit class member t (right associative)
val itt1_2 = ("f", f _) -: ("h", h)
println(itt1_2.name)
println(itt1_2.func(2))
// ("f", f _) is assigned implicit class member t (left associative)
val ist1_2 = ("f", f _) andNext ("h", h)
println(ist1_2.name)
println(ist1_2.func(2))
}
}
Have a solution. Not what I really want because in my use case
I will need more than one FuncOps but seems to work for both
scalac (2.13, 2.12) and Dotty.
Had to specify the implicit in FuncOps to match the tuple.
If anyone has a better (more general) solution, please tell me.
object Test {
import scala.language.implicitConversions
trait NamedFunc[I,O]{ self =>
def name:String
def func(i:I): O
def -:[IN](that: NamedFunc[IN,I]): NamedFunc[IN,O] = {
new NamedFunc[IN,O] {
override val name: String = that.name + " ->: " + self.name
override def func(b:IN): O = {
val first:I = that.func(b)
self.func(first)
}
}
}
def andNext[Out](that: NamedFunc[O,Out]): NamedFunc[I,Out] = {
new NamedFunc[I,Out] {
override val name: String = self.name + " andNext " + that.name
override def func(b:I): Out = {
val first:O = self.func(b)
that.func(first)
}
}
}
}
implicit def toNamedFunc[I,O](named_func: (String, I => O)): NamedFunc[I,O] = {
val nm = named_func._1
val f = named_func._2
new NamedFunc[I,O] {
override val name: String = nm
override def func(b:I): O = {
f(b)
}
}
}
implicit class FuncOps[A,B,IO,O](t: (A,B))(implicit conv: ((A,B)) => NamedFunc[IO,O]) {
private val o = conv(t)
def -:[I](that: NamedFunc[I,IO]): NamedFunc[I,O] = that.andNext(o)
def andNext[I](that: NamedFunc[O,I]): NamedFunc[IO,I] = o.andNext(that)
}
def f(a:Int):Int = -a
val h: Int => Double = (a:Int) => (2*a).toDouble
def main(args: Array[String]): Unit = {
val n1:NamedFunc[Int,Int] = ("f", f _)
val n2:NamedFunc[Int,Double] = ("h", h)
// n2 is assigned implicit class member t (right associative)
val itn1_2 = n1 -: n2
println(itn1_2.name)
println(itn1_2.func(2))
// ("h", h) is assigned implicit class member t (right associative)
val itt1_2 = ("f", f _) -: ("h", h)
println(itt1_2.name)
println(itt1_2.func(2))
// ("f", f _) is assigned implicit class member t (left associative)
val ist1_2 = ("f", f _) andNext ("h", h)
println(ist1_2.name)
println(ist1_2.func(2))
}
}