【问题标题】:Type classes for polymorphic data types in scalascala中多态数据类型的类型类
【发布时间】:2016-11-21 01:59:48
【问题描述】:

所以我在 scala 中有一个多态数据类型 Tree,定义如下

sealed trait Tree[+A]
final case class Node[A](value: A) extends Tree[A]
final case class Branch[A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]

object Tree{

  implicit def eqTree[T]: Eq[Tree[T]] = new Eq[Tree[T]] {
    override def ==(t1: Tree[T], t2: Tree[T]): Boolean = true
  }
}

还有一个类型类 Eq

trait Eq[T]{

  def == (t1: T, t2: T) : Boolean
}

我正在努力做到这一点

object App1 extends App{

  import Tree._

  def equality[T](t1: T, t2: T)(implicit eq: Eq[T]): Boolean = eq.==(t1, t2)

  println(equality(Node(1), Node(2)))
}

但是我得到以下错误

Error:(35, 19) could not find implicit value for parameter eq: typeclasses.Eq[typeclasses.Node[Int]]
  println(equality(Node(1), Node(2)))

【问题讨论】:

  • T1T2 声明在哪里?

标签: scala polymorphism typeclass implicit


【解决方案1】:

正如错误所说,编译器正在尝试查找Eq[Node[Int]],并且范围内没有这样的值。你已经定义了Eq[Tree[T]]

所以基本上这就是编译器看到的:

equality[Node[Int]](Node(1), Node(2))

但你实际上想要这个:

println(equality[Tree[Int]](Node(1), Node(2)))

【讨论】:

  • 并不是说你的观察是错误的,但我认为他的代码甚至不会编译。注意 T1 和 T2。
  • 要考虑的另一件事是==,它已经为每个对象定义了。 (定义在这里不是一个好词,因为它只是从==equals 的语法糖)
  • 我只是想看看是否可以在 scala 中获得与 haskell 等效的类型类。我知道我可以使用 ==
  • @pedrofula 这很丑,但无论如何 == 并没有为每个对象定义两个参数,因此一切正常。我还认为这只是一个错字,T1T2 应该只是T。 @Abdul Rahman 看看可以减轻痛苦的 simulacrum 库。
  • @AbdulRahman 在这种情况下,你可以做通常的事情:要么将 Eq 定义为逆变 trait Eq1[-T],要么为子类定义 Eq 实例:implicit def eqTree[T, U](implicit ev: U <:< Tree[T]): Eq[U] = new Eq[U] { override def ==(t1: U, t2: U): Boolean = true }
猜你喜欢
  • 2013-12-23
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多