在枚举上使用猫秀
Using Cats Show on enum
我需要为表达基本运算符的枚举实现 cat Show
实例。
enum Expr[T]:
case Plus(left: Expr[Double], right: Expr[Double]) extends Expr[Double]
case Minus(left: Expr[Double], right: Expr[Double]) extends Expr[Double]
case Num(value: Double) extends Expr[Double]
object Expr {
def eval[T](expr: Expr[T]): T =
expr match {
case Plus(left, right) => eval(left) + eval(right)
case Minus(left, right) => eval(left) - eval(right)
case Num(value) => value
}
看完doc后,我尝试实现如下:
object ExprShow {
implicit val numShow: Show[Expr.Num] = Show.show(
num => num.value.toString
)
implicit val minusShow: Show[Expr.Minus] = Show.show(
minus => show"${minus.left} - ${minus.right}"
)
implicit val plusShow: Show[Expr.Plus] = Show.show(
plus => show"${plus.left} + ${plus.right}"
)
}
但是我在尝试执行 show 方法时遇到错误:
val test = Expr.Num(3.0)
test.show
[error] -- [E007] Type Mismatch Error:
[error] 69 | minus => show"${minus.left} - ${minus.right}"
[error] | ^^^^^^^^^^
[error] | Found: (minus.left : grox.Expr[Double])
[error] | Required: cats.Show.Shown
[error] Explanation
[error] ===========
[error]
[error] Tree: minus.left
[error]
[error] I tried to show that
[error] (minus.left : grox.Expr[Double])
[error] conforms to
[error] cats.Show.Shown
[error] but the comparison trace ended with `false`:
[error]
[error] ==> (minus.left : grox.Expr[Double]) <: cats.Show.Shown
[error] ==> (minus.left : grox.Expr[Double]) <: cats.Show.Shown (recurring)
[error] ==> grox.Expr[Double] <: cats.Show.Shown (left is approximated)
[error] ==> grox.Expr[Double] <: cats.Show.Shown (recurring)
[error] <== grox.Expr[Double] <: cats.Show.Shown (recurring) = false
[error] <== grox.Expr[Double] <: cats.Show.Shown (left is approximated) = false
[error] <== (minus.left : grox.Expr[Double]) <: cats.Show.Shown (recurring) = false
[error] <== (minus.left : grox.Expr[Double]) <: cats.Show.Shown = false
[error]
[error] The tests were made under a constraint with:
[error] uninstantiated variables: A
[error] constrained types: [A](f: A => String): cats.Show[A],
[error] [A](f: A => String): cats.Show[A]
...
----------
[error] -- [E008] Not Found Error:
[error] 15 | test.show
[error] | ^^^^^^^^^
[error] | value show is not a member of grox.Expr[Double]
是否有任何最佳实践方法来为枚举实施 cat Show
?我的问题的根本原因是什么?任何建议或文档推荐将不胜感激。非常感谢
implicit val minusShow: Show[Expr.Minus] = Show.show(
minus => show"${minus.left} - ${minus.right}"
)
minus.left
类型是Expr[Double]
,你应该先定义Show[Expr[Double]]
这样它才能找到正确的隐式。
这是解决方案
implicit def exprShow[T]: Show[Expr[T]] = Show.show(
num => Expr.eval(num).toString
)
我需要为表达基本运算符的枚举实现 cat Show
实例。
enum Expr[T]:
case Plus(left: Expr[Double], right: Expr[Double]) extends Expr[Double]
case Minus(left: Expr[Double], right: Expr[Double]) extends Expr[Double]
case Num(value: Double) extends Expr[Double]
object Expr {
def eval[T](expr: Expr[T]): T =
expr match {
case Plus(left, right) => eval(left) + eval(right)
case Minus(left, right) => eval(left) - eval(right)
case Num(value) => value
}
看完doc后,我尝试实现如下:
object ExprShow {
implicit val numShow: Show[Expr.Num] = Show.show(
num => num.value.toString
)
implicit val minusShow: Show[Expr.Minus] = Show.show(
minus => show"${minus.left} - ${minus.right}"
)
implicit val plusShow: Show[Expr.Plus] = Show.show(
plus => show"${plus.left} + ${plus.right}"
)
}
但是我在尝试执行 show 方法时遇到错误:
val test = Expr.Num(3.0)
test.show
[error] -- [E007] Type Mismatch Error:
[error] 69 | minus => show"${minus.left} - ${minus.right}"
[error] | ^^^^^^^^^^
[error] | Found: (minus.left : grox.Expr[Double])
[error] | Required: cats.Show.Shown
[error] Explanation
[error] ===========
[error]
[error] Tree: minus.left
[error]
[error] I tried to show that
[error] (minus.left : grox.Expr[Double])
[error] conforms to
[error] cats.Show.Shown
[error] but the comparison trace ended with `false`:
[error]
[error] ==> (minus.left : grox.Expr[Double]) <: cats.Show.Shown
[error] ==> (minus.left : grox.Expr[Double]) <: cats.Show.Shown (recurring)
[error] ==> grox.Expr[Double] <: cats.Show.Shown (left is approximated)
[error] ==> grox.Expr[Double] <: cats.Show.Shown (recurring)
[error] <== grox.Expr[Double] <: cats.Show.Shown (recurring) = false
[error] <== grox.Expr[Double] <: cats.Show.Shown (left is approximated) = false
[error] <== (minus.left : grox.Expr[Double]) <: cats.Show.Shown (recurring) = false
[error] <== (minus.left : grox.Expr[Double]) <: cats.Show.Shown = false
[error]
[error] The tests were made under a constraint with:
[error] uninstantiated variables: A
[error] constrained types: [A](f: A => String): cats.Show[A],
[error] [A](f: A => String): cats.Show[A]
...
----------
[error] -- [E008] Not Found Error:
[error] 15 | test.show
[error] | ^^^^^^^^^
[error] | value show is not a member of grox.Expr[Double]
是否有任何最佳实践方法来为枚举实施 cat Show
?我的问题的根本原因是什么?任何建议或文档推荐将不胜感激。非常感谢
implicit val minusShow: Show[Expr.Minus] = Show.show(
minus => show"${minus.left} - ${minus.right}"
)
minus.left
类型是Expr[Double]
,你应该先定义Show[Expr[Double]]
这样它才能找到正确的隐式。
这是解决方案
implicit def exprShow[T]: Show[Expr[T]] = Show.show(
num => Expr.eval(num).toString
)