简体   繁体   中英

could not find implicit value for parameter semigroupal

I just tried to compile the following code:

import cats.Monoid
import cats.instances.boolean._ // for Monoid
import cats.instances.int._ // for Monoid
import cats.instances.list._ // for Monoid
import cats.instances.string._ // for Monoid
import cats.syntax.apply._ // for imapN
import cats.syntax.semigroup._

case class Cat2(name: String, yearOfBirth: Int, favoriteFoods: List[String])

object FancyFunctor {

  val tupleToCat: (String, Int, List[String]) => Cat2 =
    Cat2.apply _

  val catToTuple: Cat2 => (String, Int, List[String]) =
    cat => (cat.name, cat.yearOfBirth, cat.favoriteFoods)

  implicit val catMonoid: Monoid[Cat2] = (
    Monoid[String],
    Monoid[Int],
    Monoid[List[String]]
  ).imapN(tupleToCat)(catToTuple)

  def main(args: Array[String]): Unit = {

    val garfield = Cat2("Garfield", 1978, List("Lasagne"))
    val heathcliff = Cat2("Heathcliff", 1988, List("Junk Food"))

    val a = garfield |+| heathcliff

  }

}

And I've got the error message:

[info] Compiling 1 Scala source to /home/developer/Desktop/scala/catssemigroupal/target/scala-2.12/classes ...
[error] /home/developer/Desktop/scala/catssemigroupal/src/main/scala/io/khinkali/FancyFunctor.scala:25:22: could not find implicit value for parameter semigroupal: cats.Semigroupal[cats.kernel.Monoid]
[error]   ).imapN(tupleToCat)(catToTuple)
[error]                      ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed Feb 24, 2018, 10:18:01 PM

What am I doing wrong?

This compiles with cats 1.0.1:

import cats.Monoid
import cats.instances.boolean._ // for Monoid
import cats.instances.int._ // for Monoid
import cats.instances.list._ // for Monoid
import cats.instances.string._ // for Monoid
import cats.syntax.apply._ // for imapN
import cats.syntax.semigroup._ // for |+|
import cats.instances.invariant._ // for  catsSemigroupalForMonoid: InvariantSemigroupal[Monoid] 

object FancyFunctor {

  /*
  val tupleToCat: (String, Int, List[String]) => Cat2 =
    Cat2.apply _

  val catToTuple: Cat2 => (String, Int, List[String]) =
    cat => (cat.name, cat.yearOfBirth, cat.favoriteFoods)

  */

  case class Cat2(name: String, yearOfBirth: Int, favoriteFoods: List[String])
  implicit val catMonoid: Monoid[Cat2] = (
    Monoid[String],
    Monoid[Int],
    Monoid[List[String]]
  ).imapN(Cat2.apply)(c => Cat2.unapply(c).get)

  def main(args: Array[String]): Unit = {

    val garfield = Cat2("Garfield", 1978, List("Lasagne"))
    val heathcliff = Cat2("Heathcliff", 1988, List("Junk Food"))

    val a = garfield |+| heathcliff

  }

}

How to find quickly using nothing but a browser (without IDE):

  • Search for Semigroupal (the missing typeclass) in the Doc
  • Search for Monoid using text-search of the browser on the result page
  • Click on the implicit method that returns Semigroupal[Monoid] ,
  • Follow the links to the defining class: InvariantMonoidalInstances
  • Look for linear subclasses, pick something more precise than "all"

Hint: the overkill-approach cats.implicits._ works on your code.


As a bonus: you don't have to redefine Cat2.apply and Cat2.unapply , they are automatically provided for every case -class.

I also got a bit puzzled by this problem when reading the book (and what an amazing book it is!). Two things helped me realize that I needed the Invariant type class coming from import cats.instances.invariant._ :

1) The text above the code says

For example, we can combine Monoids using Invariant

And yet there is no invariant visible in scope!

2) If you click on the imapN method you will see that it takes two implicit parameters implicit invariant: Invariant[F], semigroupal: Semigroupal[F]

These two things combined make you look for a way to add Invariant in scope. And since throughout the book the prevalent way of doing this is to get them from cats.instances... that's what I did. Hope it makes sense.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM