1

Scala with Catsという本を読んでいます。scala 型システムの機微を理解しようとしています。次の例を思いつきました。

object Example extends App {

  sealed trait Serializer[T] {
    def serialize(seq: List[T]): String
  }

  implicit object StringSerializer extends Serializer[String] {
    def serialize(seq: List[String]): String = seq.toString()
  }

  implicit object IntSerializer extends Serializer[Int] {
    def serialize(seq: List[Int]): String =  seq.toString()
  }

  def f1[T0 : Serializer](x: List[List[T0]])(implicit s0: Serializer[T0]): List[String] = {
    x.map(lst => s0.serialize(lst))
  }
  
  // some dummy data
  val col1 = List("a", "b", "c", "d", "e")
  val col2 = List(12, 200, 80900, 201200, 124420000)
  val col3 = List(121, 12121, 71240000, 44356, 845)
  val data = List(col1, col2, col3)
  
  f1(data)
}

これはコンパイルされず、次のエラーが表示されます。

タイプ Example.Serializer[Any] の証拠パラメーターの暗黙的な値が見つかりませんでした

なぜこれが起こるのか理解できました。それは私の関数f1によるものです。List[Int] と List[String] を関数に渡したので、共通の親の型は Any です。そのため、タイプ情報が消去され、シリアライザーに渡されます。

ただし、コンテキストをバインドした場合、コンパイラはこれが行われる前に暗黙の定義を最初に探すべきではありませんか? 明らかにそうではないので、私の理解は間違っています。この問題を回避する Scala の方法は何ですか。

どんな説明でも大歓迎です!

4

1 に答える 1