Scala与Cats:数值类型转Id[T]调用sumOfSquares时Monad隐式缺失问题
Hey there! Let's dig into why you're hitting that could not find implicit value for evidence parameter of type cats.Monad[[A]Any] error when trying to use your sumOfSquares function with Id[T].
First, let's break down the root issue
That error sounds scary, but it boils down to this: the compiler can't find a Monad instance for the type it's inferring (in this case, Any), but Cats absolutely provides a Monad[Id] instance—the problem is likely in your imports, function signature, or how you're calling the function.
Step-by-step fixes
1. Make sure you're importing the right Cats utilities
First, double-check you have the necessary imports to pull in Monad[Id] and other implicit instances. Add these at the top of your file:
import cats._ import cats.implicits._
Skipping these imports is the most common reason the compiler can't find the Monad[Id] instance.
2. Fix your sumOfSquares function signature
Since Id[T] is just a type alias for T (type Id[A] = A), you don't need an explicit implicit conversion from T to Id[T]—they're the same type! A well-formed sumOfSquares that works with Id (and any other Monad) might look like this:
def sumOfSquares[F[_]: Monad, T: Numeric](values: F[T]): F[Double] = { val numeric = implicitly[Numeric[T]] // Map each value to its square, then fold to sum them values.map(t => numeric.toDouble(t) * numeric.toDouble(t)) .foldLeft(0.0.pure[F]) { (acc, square) => acc.flatMap(total => square.map(s => total + s)) } }
This version uses Numeric[T] to handle any numeric type, and Monad[F] to support Id, Option, List, etc.
3. Fix the call site to guide type inference
Your error happens at the println line because the compiler is incorrectly inferring F[_] as Any instead of Id. Fix this by either:
- Explicitly specifying the type parameters when calling the function:
val intSum = sumOfSquares[Id, Int](List(1, 2, 3)) println(s"Sum of squares for int $intSum") - Or leveraging the fact that
Id[T]is justT—you can pass a regular value directly (no need to wrap it inId):// Since Id[List[Int]] is just List[Int] val intSum = sumOfSquares(List(1, 2, 3)) println(s"Sum of squares for int $intSum")
Full working example
Here's a complete snippet you can test:
import cats._ import cats.implicits._ def sumOfSquares[F[_]: Monad, T: Numeric](values: F[T]): F[Double] = { val numeric = implicitly[Numeric[T]] values.map(t => numeric.toDouble(t) * numeric.toDouble(t)) .foldLeft(0.0.pure[F]) { (acc, square) => acc.flatMap(total => square.map(s => total + s)) } } // Test with Id (which is just the raw type) val intSum = sumOfSquares[Id, Int](List(1, 2, 3)) println(s"Sum of squares for int $intSum") // Output: Sum of squares for int 14.0 // Test with another Monad (like Option) to prove flexibility val optSum = sumOfSquares(Option(5)) println(s"Sum of squares for Option: $optSum") // Output: Sum of squares for Option: Some(25.0)
内容的提问来源于stack exchange,提问作者Viswanath




