To be honest I am not sure if I am asking the right question. I suppose I may completely misunderstanding the point, but here is my question. I understand the basic way of creating type class as typical example like Show, which in my viewpoint it uses default constructor to create instance implicitly as below
trait Show[T] {
def show(msg: T): String
}
object Show {
def apply[T](implicit s: Show[T]) = s
def show[A: Show](msg: A) = Show[A].show(msg)
implicit val intShow = new Show[Int] {
override def show(msg: Int) = s"msg: $msg"
}
}
object MyExample {
def main(args: Array[String]): Unit = {
import Show._
println(show(3))
}
}
But now I have a problem. If I have a trait instance that may take some other inputs during instance creation. For instance, new Service(service1, service2) where service1 and service2 may be another input. How can I construct the implicit instance in such case. What I can think of is to define an implicit function that takes input(s) and use that function to instantiate the instance, but this seems to me implicit is useless (because I have to explicitly use it). Generally what would be recommended to deal with such case? Thanks
trait Service[I, O] {
def run(): O
}
object Service {
def apply[I, O](implicit s: Service[I, O]) = s
implicit def service[I, O](in: I, f: I => O) = new Service[I, O] {
def run(): O = f(in)
}
}
object Another {
def main(args: Array[String]): Unit = {
import Service._
val inc = (in: Int) => in + 1
val s = service(3, inc)
println(s.run())
}
}