不明确的隐式值:匹配预期类型 cats.derived.MkShow[A]:显示 cats:kittens
ambiguous implicit values: match expected type cats.derived.MkShow[A]: show cats:kittens
我正在尝试为我的自定义配置创建显示实例 class。
build.sbt 文件是 -
name := "circe-demo"
version := "0.1"
scalaVersion := "2.11.12"
resolvers += Resolver.bintrayRepo("ovotech", "maven")
libraryDependencies += "io.circe" %% "circe-core" % "0.11.0"
libraryDependencies += "io.circe" %% "circe-parser" % "0.11.0"
libraryDependencies += "io.circe" %% "circe-generic" % "0.11.0"
libraryDependencies += "org.typelevel" %% "kittens" % "1.2.0"
libraryDependencies ++= Seq(
"is.cir" %% "ciris-cats",
"is.cir" %% "ciris-cats-effect",
"is.cir" %% "ciris-core",
"is.cir" %% "ciris-enumeratum",
"is.cir" %% "ciris-refined"
).map(_ % "0.12.1")
完整代码为-
import enumeratum.{Enum, EnumEntry}
sealed abstract class AppEnvironment extends EnumEntry
object AppEnvironment extends Enum[AppEnvironment] {
case object Local extends AppEnvironment
case object Testing extends AppEnvironment
case object Production extends AppEnvironment
override val values: Vector[AppEnvironment] =
findValues.toVector
}
import java.net.InetAddress
import scala.concurrent.duration.Duration
final case class ApiConfig(host: InetAddress, port: Int, apiKey: String, timeout: Duration)
import java.net.InetAddress
import cats.Show
import cats.derived.semi
import ciris.config.loader.AppEnvironment.{Local, Production, Testing}
import enumeratum.EnumEntry
import eu.timepit.refined.auto._
import eu.timepit.refined.types.string.NonEmptyString
import scala.concurrent.duration._
final case class Config(appName: NonEmptyString, environment: AppEnvironment, api: ApiConfig)
object Config {
implicit val showConfig: Show[Config] = {
implicit val showDuration: Show[Duration] =
Show.fromToString
implicit val showInetAddress: Show[InetAddress] =
Show.fromToString
implicit def showEnumEntry[E <: EnumEntry]: Show[E] =
Show.show(_.entryName)
// Show.show[Config](x => s"api = ${x.api} appName = ${x.appName} environment ${x.environment}")
semi.show
}
}
上面代码中的 semi.show
抛出以下异常 -
[error] /Users/rajkumar.natarajan/Documents/Coding/kafka_demo/circe-demo/src/main/scala/ciris/config/loader/Config.scala:32:5: ambiguous implicit values:
[error] both value emptyProductDerivedShow in trait MkShowDerivation of type => cats.derived.MkShow[shapeless.HNil]
[error] and method emptyCoproductDerivedShow in trait MkShowDerivation of type => cats.derived.MkShow[shapeless.CNil]
[error] match expected type cats.derived.MkShow[A]
[error] show
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error]
我是使用猫进行函数式编程的新手。
我该如何解决这个异常。
不幸的是,当涉及到如此复杂的隐式和宏时,错误报告远非完美。您看到的消息实际上意味着尚未找到真正的生成器(在本例中为 MkShow.genericDerivedShowProduct
)所需的一些隐含项,并且搜索返回到一些存在歧义的基本内容。缺少的东西大多是非常基本的,例如 Show[Int]
或 Show[String]
的隐式。获得它们的最简单方法是 import cats.implicits._
,但这也会带来 catsStdShowForDuration
,即 Show[Duration]
。但由于它的实现与您的自定义实现完全相同,因此更容易删除您的自定义实现。缺少的另一件事是 Show[NonEmptyString]
并且很容易创建一个
implicit def showNonEmptyString: Show[NonEmptyString] = Show.show(nes => nes)
总而言之,当我将你的 showConfig
定义为
implicit val showConfig: Show[Config] = {
import cats.implicits._
// is already defined in cats.implicits._
//implicit val showDuration: Show[Duration] = Show.fromToString
implicit val showInetAddress: Show[InetAddress] = Show.fromToString
implicit def showEnumEntry[E <: EnumEntry]: Show[E] = Show.show(_.entryName)
implicit def showNonEmptyString: Show[NonEmptyString] = Show.show(nes => nes)
// Show.show[Config](x => s"api = ${x.api} appName = ${x.appName} environment ${x.environment}")
semi.show
}
它为我编译。
P.S。将 AppEnvironment
放在 ciris.*
包下有什么好的理由吗?我想说的是,通常将您的自定义代码放入第 3 方库的包中很容易把事情搞砸。
我正在尝试为我的自定义配置创建显示实例 class。
build.sbt 文件是 -
name := "circe-demo"
version := "0.1"
scalaVersion := "2.11.12"
resolvers += Resolver.bintrayRepo("ovotech", "maven")
libraryDependencies += "io.circe" %% "circe-core" % "0.11.0"
libraryDependencies += "io.circe" %% "circe-parser" % "0.11.0"
libraryDependencies += "io.circe" %% "circe-generic" % "0.11.0"
libraryDependencies += "org.typelevel" %% "kittens" % "1.2.0"
libraryDependencies ++= Seq(
"is.cir" %% "ciris-cats",
"is.cir" %% "ciris-cats-effect",
"is.cir" %% "ciris-core",
"is.cir" %% "ciris-enumeratum",
"is.cir" %% "ciris-refined"
).map(_ % "0.12.1")
完整代码为-
import enumeratum.{Enum, EnumEntry}
sealed abstract class AppEnvironment extends EnumEntry
object AppEnvironment extends Enum[AppEnvironment] {
case object Local extends AppEnvironment
case object Testing extends AppEnvironment
case object Production extends AppEnvironment
override val values: Vector[AppEnvironment] =
findValues.toVector
}
import java.net.InetAddress
import scala.concurrent.duration.Duration
final case class ApiConfig(host: InetAddress, port: Int, apiKey: String, timeout: Duration)
import java.net.InetAddress
import cats.Show
import cats.derived.semi
import ciris.config.loader.AppEnvironment.{Local, Production, Testing}
import enumeratum.EnumEntry
import eu.timepit.refined.auto._
import eu.timepit.refined.types.string.NonEmptyString
import scala.concurrent.duration._
final case class Config(appName: NonEmptyString, environment: AppEnvironment, api: ApiConfig)
object Config {
implicit val showConfig: Show[Config] = {
implicit val showDuration: Show[Duration] =
Show.fromToString
implicit val showInetAddress: Show[InetAddress] =
Show.fromToString
implicit def showEnumEntry[E <: EnumEntry]: Show[E] =
Show.show(_.entryName)
// Show.show[Config](x => s"api = ${x.api} appName = ${x.appName} environment ${x.environment}")
semi.show
}
}
上面代码中的 semi.show
抛出以下异常 -
[error] /Users/rajkumar.natarajan/Documents/Coding/kafka_demo/circe-demo/src/main/scala/ciris/config/loader/Config.scala:32:5: ambiguous implicit values:
[error] both value emptyProductDerivedShow in trait MkShowDerivation of type => cats.derived.MkShow[shapeless.HNil]
[error] and method emptyCoproductDerivedShow in trait MkShowDerivation of type => cats.derived.MkShow[shapeless.CNil]
[error] match expected type cats.derived.MkShow[A]
[error] show
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error]
我是使用猫进行函数式编程的新手。 我该如何解决这个异常。
不幸的是,当涉及到如此复杂的隐式和宏时,错误报告远非完美。您看到的消息实际上意味着尚未找到真正的生成器(在本例中为 MkShow.genericDerivedShowProduct
)所需的一些隐含项,并且搜索返回到一些存在歧义的基本内容。缺少的东西大多是非常基本的,例如 Show[Int]
或 Show[String]
的隐式。获得它们的最简单方法是 import cats.implicits._
,但这也会带来 catsStdShowForDuration
,即 Show[Duration]
。但由于它的实现与您的自定义实现完全相同,因此更容易删除您的自定义实现。缺少的另一件事是 Show[NonEmptyString]
并且很容易创建一个
implicit def showNonEmptyString: Show[NonEmptyString] = Show.show(nes => nes)
总而言之,当我将你的 showConfig
定义为
implicit val showConfig: Show[Config] = {
import cats.implicits._
// is already defined in cats.implicits._
//implicit val showDuration: Show[Duration] = Show.fromToString
implicit val showInetAddress: Show[InetAddress] = Show.fromToString
implicit def showEnumEntry[E <: EnumEntry]: Show[E] = Show.show(_.entryName)
implicit def showNonEmptyString: Show[NonEmptyString] = Show.show(nes => nes)
// Show.show[Config](x => s"api = ${x.api} appName = ${x.appName} environment ${x.environment}")
semi.show
}
它为我编译。
P.S。将 AppEnvironment
放在 ciris.*
包下有什么好的理由吗?我想说的是,通常将您的自定义代码放入第 3 方库的包中很容易把事情搞砸。