Skip to content

Instantly share code, notes, and snippets.

@henoc
Created September 26, 2017 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henoc/d1318b53eec3fb05202d6cb343a28211 to your computer and use it in GitHub Desktop.
Save henoc/d1318b53eec3fb05202d6cb343a28211 to your computer and use it in GitHub Desktop.
ある型クラスを実装する任意クラスのインスタンス列が持てるやつ
import org.scalatest.FunSuite
import simulacrum.typeclass
import scala.language.higherKinds
class TypeClassTest extends FunSuite {
test("box!") {
// 型クラス Show
@typeclass trait Show[T] {
def show(self: T): String = self.toString
}
import Show.ops._
// Show は Int, String, Boolean について実装されているとする
implicit val showInt = new Show[Int] {}
implicit val showString = new Show[String] {}
implicit val showBoolean = new Show[Boolean] {}
// 型クラス Box はある要素contentとその型が実装する1つの型クラスのインスタンスを保有する
// F: Contentが実装している型クラス
trait Box[F[_]] {
type Content
val content: Content
val typeClassImpl: F[Content]
}
// Box は A について実装される
implicit def boxed[A, F[_]](cont: A)(implicit tci: F[A]): Box[F] = new Box[F] {
override type Content = A
override val content: Content = cont
override val typeClassImpl: F[Content] = tci
}
// Showを実装しているインスタンスを集めて使いたい
class Collector(val seq: Seq[Box[Show]]) {
def showAll(): Unit = {
for (i <- seq) {
// Show[i.Content] 型
implicit val iContentShow = i.typeClassImpl
// 使える
println(i.content.show)
}
}
}
object Collector {
def apply(a: Box[Show]*) = new Collector(a)
}
val collector = Collector(100, "aaa", true)
collector.showAll()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment