package tt object ChannelTest extends App { def process[T: Operation](channelId: Long): T = { val channel = ChannelService.byId(channelId) val op = implicitly[Operation[T]] // specific operation depending on concrete T val t: T = op.read(channel) op.write(channel, t) t } import Implicits._ val x: Int = process[Int](1L) val y: String = process[String](2L) } case class Channel(channelId: Long) object ChannelService { def byId(channelId: Long) = Channel(channelId) } trait Operation[T] { def read(channel: Channel): T def write(channel: Channel, t: T): Unit } object Implicits { implicit val intOp: Operation[Int] = new Operation[Int] { def read(channel: Channel): Int = { println("intOp.read") channel.toString.length } def write(channel: Channel, t: Int): Unit = { println("intOp.write") } } implicit val stringOp: Operation[String] = new Operation[String] { def read(channel: Channel): String = { println("stringOp.read") channel.toString } def write(channel: Channel, t: String): Unit = { println("stringOp.write") } } }