I have a function that computes sum of squares for numeric types as shown below.
import cats.syntax.functor._
import cats.syntax.applicative._
import cats.{Id, Monad}
import scala.language.higherKinds
object PowerOfMonads {
/**
* Ultimate sum of squares method
*
* @param x First value in context
* @param y Second value in context
* @tparam F Monadic context
* @tparam T Type parameter in the Monad
* @return Sum of squares of first and second values in the Monadic context
*/
def sumOfSquares[F[_]: Monad, A, T >: A](x: F[A], y: F[A])(implicit num: Numeric[T]) : F[T] = {
def square(value:T): T = num.times(value, value)
def sum(first:T, second:T): T = num.plus(first, second)
for {
first <- x
second <- y
} yield sum(square(first), square(second))
}
}
From the client code, I would like to utilise the function as shown below
import cats.Id
import cats.instances.future._
import cats.instances.list._
import cats.instances.option._
import cats.syntax.applicative._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
println(s"Sum of squares for list ${PowerOfMonads.sumOfSquares( List(1,2,3), List(1,2,3) )}")
println(s"Sum of squares for options ${PowerOfMonads.sumOfSquares( Option(1), 2.pure[Option] )}")
println(s"Sum of squares for future ${PowerOfMonads.sumOfSquares( 1.pure[Future], Future(2) ).value}")
println(s"Sum of squares for id ${PowerOfMonads.sumOfSquares(1.pure[Id], 2.pure[Id])}")
Now, I would like to use implicit conversion from a numeric type T to Id[T] to invoke the function sumOfSquares as shown below
println(s"Sum of squares for int ${PowerOfMonads.sumOfSquares(1, 2)}")
using a function as shown below
import cats.syntax.applicative._
import scala.language.implicitConversions
/**
* Implicit conversion for any numeric type T to Id[T]
* @param value value with type T
* @tparam T numeric type
* @return numeric type wrapped in the context of an Identity Monad
*/
implicit def anyNum2Id[T](value:T)(implicit num: Numeric[T]):Id[T] = value.pure[Id]
However, when executing the program, I get the following errors
could not find implicit value for evidence parameter of type cats.Monad[[A]Any] println(s"Sum of squares for int
${PowerOfMonads.sumOfSquares(1, 2)}") not enough arguments for method sumOfSquares: (implicit evidence$1: cats.Monad[[A]Any], implicit num: Numeric[T])Any. Unspecified value parameters evidence$1, num. println(s"Sum of squares for int ${PowerOfMonads.sumOfSquares(1, 2)}")
Please help me resolve the error.
cats
versions you are using? It doesn't seem to compile out of the box, at least not with my settings:PowerOfMonads
gives "valueflatMap
is not a member of type parameterF[A]
:first <- x
" – Andrey TyukinList
version of the client code fail? For theId
case, have you tried specifying the type parameter in the function call? What I see from the error logs is that the interpreter is not guessing that the type would beId
and tries to find evidence of Monad and Numberic for typeAny
– EugeInt
toId
. Even if it was the only choice, it has to search for all other possible choices to get to the conclusion that it was in fact the only one. It's beyond the bounds of computability I'd say. – Euge