【发布时间】:2017-11-17 18:59:32
【问题描述】:
我正在阅读 ScalaZ tutorial,现在我在 Yes-No 类型课程的部分。最终目标是将1.truthy 变为return true。这是类型类的实现:
trait CanTruthy[A] { self =>
/** @return true, if `a` is truthy. */
def truthys(a: A): Boolean
}
object CanTruthy {
def apply[A](implicit ev: CanTruthy[A]): CanTruthy[A] = ev
def truthys[A](f: A => Boolean): CanTruthy[A] = new CanTruthy[A] {
def truthys(a: A): Boolean = f(a)
}
}
trait CanTruthyOps[A] {
def self: A
implicit def F: CanTruthy[A]
final def truthy: Boolean = F.truthys(self)
}
object ToCanIsTruthyOps {
implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A]) =
new CanTruthyOps[A] {
def self = v
implicit def F: CanTruthy[A] = ev
}
}
implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({
case 0 => false
case _ => true
})
对我来说看起来有点吓人。我们引入了 2 个新特性来实现这一目标。但是我们可以通过使用隐式类来达到同样的效果:
trait CanTruthy {
def truthy: Boolean
}
object CanTruthy{
implicit class CanTruthyInt(i: Int) extends CanTruthy{
override def truthy: Boolean = i match {
case 0 => false
case _ => true
}
}
}
在我看来是一样的。那么为什么我们需要使用教程中的方式呢?我错过了什么?你能解释一下有什么区别吗?
【问题讨论】:
-
我认为你是对的,如果你只想这样,你的方式会更好。
-
@FedericoSawady 这就是我问的原因。我可以用第一种方法做哪些我不能用第二种方法做的事情。
-
你如何用你的定义来定义对真值的操作?
-
@FedericoSawady 不太明白。真实值是布尔值。操作已定义。
-
想想像 javascript、C++ 等语言中的真实值,即在不同场景中解释为布尔值的值。我可以定义
1 || 0,这将导致true。换句话说,我可以定义真值之间的操作,因此您可能希望将真值封装在一个对象中。这就是为什么我要问你如何定义这种操作。