MeWrite Docs

Scala: could not find implicit value

Scalaで暗黙の値が見つからない場合のエラー

概要

Scalaで暗黙のパラメータや暗黙の変換に必要な値がスコープ内に見つからない場合に発生するコンパイルエラーです。

エラーメッセージ

could not find implicit value for parameter encoder: Encoder[MyClass]

または

No implicit Ordering defined for MyClass

原因

  1. インポート不足: 必要な暗黙の値をインポートしていない
  2. 型クラスインスタンス未定義: カスタム型に対するインスタンスがない
  3. スコープの問題: 暗黙の値が見えないスコープにある
  4. 型パラメータの不一致: ジェネリック型の型引数が合わない

解決策

1. 必要なインポートを追加

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 悪い例
val list = List(3, 1, 2)
list.sorted  // Ordering[Int]が見つからない(通常は自動)

// 良い例:カスタム型の場合
import scala.math.Ordering.Implicits._

case class Person(name: String, age: Int)
implicit val personOrdering: Ordering[Person] = Ordering.by(_.age)

val people = List(Person("A", 30), Person("B", 20))
people.sorted  // ageでソート

2. 型クラスインスタンスを定義

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// JSON エンコーダーの例(circe)
import io.circe._
import io.circe.generic.semiauto._

case class User(id: Int, name: String)

// 悪い例:Encoderがない
// Json.toJson(user)  // could not find implicit value

// 良い例:deriveEncoderでインスタンス生成
implicit val userEncoder: Encoder[User] = deriveEncoder[User]
implicit val userDecoder: Decoder[User] = deriveDecoder[User]

3. コンパニオンオブジェクトに配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
case class Money(amount: BigDecimal, currency: String)

object Money {
  // コンパニオンオブジェクトは自動的にスコープに入る
  implicit val moneyOrdering: Ordering[Money] = Ordering.by(_.amount)

  implicit val moneyEncoder: Encoder[Money] = deriveEncoder
}

// 使用時にインポート不要
val moneys = List(Money(100, "JPY"), Money(50, "JPY"))
moneys.sorted  // 自動的にmoney.moneyOrderingが使われる

4. 明示的に渡す

1
2
3
4
5
6
def process[T](data: T)(implicit encoder: Encoder[T]): String = {
  encoder(data).noSpaces
}

// 暗黙の値がない場合は明示的に渡す
process(myData)(customEncoder)

5. implicitly で確認

1
2
3
// スコープ内の暗黙の値を確認
val ord = implicitly[Ordering[Int]]  // 見つかる
val enc = implicitly[Encoder[MyClass]]  // エラーで問題箇所が分かる

6. Scala 3 (given/using)

1
2
3
4
5
6
7
8
9
// Scala 3 の構文
case class User(name: String)

// given で暗黙の値を定義
given Ordering[User] = Ordering.by(_.name)

// using で暗黙のパラメータを宣言
def sortUsers(users: List[User])(using ord: Ordering[User]): List[User] =
  users.sorted

7. 自動導出(magnolia/shapeless)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// magnoliaで自動導出
import magnolia1._

trait Show[T] {
  def show(value: T): String
}

object Show extends AutoDerivation[Show] {
  def join[T](ctx: CaseClass[Show, T]): Show[T] = value =>
    ctx.parameters.map(p => s"${p.label}=${p.typeclass.show(p.dereference(value))}").mkString(", ")
}

よくある間違い

  • 暗黙の値をprivateで定義している
  • 型パラメータが具体化されていない(Encoder[T]ではなくEncoder[List[T]]が必要)
  • 循環する暗黙の定義
  • 優先順位の競合(複数の暗黙の値が候補になる)

Scala の他のエラー

最終更新: 2025-12-09