在 Scala 中为元组编写类型类 [英] Composing typeclasses for tuples in Scala

查看:41
本文介绍了在 Scala 中为元组编写类型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找抽象来组合类型类并避免样板代码:

I am looking for abstraction to compose typeclasses and 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 a
                                               adder2 add b
                               }
                }


}

有无样板的方法吗?也许是无形的?

Is there a boilerplate free approach ? Maybe in shapeless ?

推荐答案

是的,Shapeless 可以在这里帮助您,它的 TypeClass 类型类:

Yep, Shapeless can help you here, with its TypeClass type class:

trait Something

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]

然后:

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 my blog post here for some additional discussion.

这篇关于在 Scala 中为元组编写类型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆