shapeless - Composing typeclasses for tuples in Scala -
shapeless - Composing typeclasses for tuples in Scala -
i looking abstraction compose typeclasses , avoid boilerplate code:
sealed trait mytypeclass[t]{ def add(t:t, mystuff:something) } object mytypeclass { implicit def tupled[a,b](implicit adder1: mytypeclass [a],adder2: mytypeclass [b]): mytypeclass [(a,b)] = new mytypeclass [(a, b)] { override def add(t: (a, b), mystuff: something): unit = { val (a,b) = t adder1 add together adder2 add together b } } }
is there boilerplate free approach ? maybe in shapeless ?
yep, shapeless can help here, typeclass
type class:
trait sealed trait mytypeclass[a] { def add(a: a, mystuff: something) } import shapeless._ implicit object mytypeclasstypeclass extends producttypeclass[mytypeclass] { def product[h, t <: hlist](htc: mytypeclass[h], ttc: mytypeclass[t]) = new mytypeclass[h :: t] { def add(a: h :: t, mystuff: something): unit = { htc.add(a.head, mystuff) ttc.add(a.tail, mystuff) } } def emptyproduct = new mytypeclass[hnil] { def add(a: hnil, mystuff: something): unit = () } def project[f, g](instance: => mytypeclass[g], to: f => g, from: g => f) = new mytypeclass[f] { def add(a: f, mystuff: something): unit = { instance.add(to(a), mystuff) } } } object mytypeclasshelper extends producttypeclasscompanion[mytypeclass]
and then:
scala> implicit object intmytypeclass extends mytypeclass[int] { | def add(a: int, mystuff: something): unit = { | println(s"adding $a") | } | } defined module intmytypeclass scala> import mytypeclasshelper.auto._ import mytypeclasshelper.auto._ scala> implicitly[mytypeclass[(int, int)]] res0: mytypeclass[(int, int)] = mytypeclasstypeclass$$anon$3@18e713e0 scala> implicitly[mytypeclass[(int, int, int)]] res1: mytypeclass[(int, int, int)] = mytypeclasstypeclass$$anon$3@53c29556
see blog post here additional discussion.
scala shapeless
Comments
Post a Comment