These are chat archives for scalajp/functional

25th
Apr 2015
Sanshiro Yoshida
@halcat0x15a
Apr 25 2015 06:40

GHC.Genericsっぽいもの書いてるんですけど、implicitの解決で再帰してStackOverflowしちゃうんですが何かいい方法ありますか。

trait Generic[A] {
  type Repr
  def to(rep: Repr): A
  def from(a: A): Repr
}

object Generic {
  type Type[A, R] = Generic[A] { type Repr = R }
}

sealed trait Tree[+A]
case class Node[A](left: Tree[A], value: A, right: Tree[A]) extends Tree[A]
case object Leaf extends Tree[Nothing]

trait Equal[A] {
  def equal(x: A, y: A): Boolean
}

object Equal {
  implicit def unit = new Equal[Unit] {
    def equal(x: Unit, y: Unit) = true
  }
  implicit def either[A, B](implicit A: Equal[A], B: Equal[B]) = new Equal[Either[A, B]] {
    def equal(x: Either[A, B], y: Either[A, B]) = (x, y) match {
      case (Left(x), Left(y)) => A.equal(x, y)
      case (Right(x), Right(y)) => B.equal(x, y)
      case _ => false
    }
  }
  implicit def tuple[A, B](implicit A: Equal[A], B: Equal[B]) = new Equal[(A, B)] {
    def equal(x: (A, B), y: (A, B)) = A.equal(x._1, y._1) && B.equal(x._2, y._2)
  }
  def generic[A, R](implicit A: Generic.Type[A, R], R: Equal[R]): Equal[A] = new Equal[A] {
    def equal(x: A, y: A) = R.equal(A.from(x), A.from(y))
  }
  def rec[A](A: => Equal[A]) = new Equal[A] { def equal(x: A, y: A) = A.equal(x, y) }
}

object Tree {
  implicit def generic[A] = new Generic[Tree[A]] {
    type Repr = Either[(Tree[A], (A, Tree[A])), Unit]
    def to(rep: Repr): Tree[A] = rep match {
      case Left((left, (value, right))) => Node(left, value, right)
      case Right(()) => Leaf
    }
    def from(tree: Tree[A]): Repr = tree match {
      case Node(left, value, right) => Left((left, (value, right)))
      case Leaf => Right(())
    }
  }
  implicit def equal[A](implicit A: Equal[A]): Equal[Tree[A]] = Equal.rec(Equal.generic)
}

いちおうλ抽象すれば動くけど汎用的(型クラス毎に書かずに済むよう)にしたいです。

kenji yoshida
@xuwei-k
Apr 25 2015 06:41
shapeless.Lazy ?
Sanshiro Yoshida
@halcat0x15a
Apr 25 2015 06:42
みてみますー
kenji yoshida
@xuwei-k
Apr 25 2015 06:42
というか実用的には、shapeless.Generic 使えばいいとおもうけど、なぜわざわざ手で書いてるのか・・・
shapeless.Generic と shapeless.Typeclass か
Sanshiro Yoshida
@halcat0x15a
Apr 25 2015 06:46
コンパクトに実装できたらkitsにいれようかと。
kenji yoshida
@xuwei-k
Apr 25 2015 06:47
マクロ使わないという話?
Sanshiro Yoshida
@halcat0x15a
Apr 25 2015 06:50
マクロは使うと思います。shapelessのはいろいろくっついててそのまま持ってこれないので。
macroでLazy生成してるのか。shapelessぱない…