#scala #scala-cats
#scala #scala-кошки
Вопрос:
У меня есть следующий код, который я не могу понять, в чем разница:
implicit def boxPrintable[A](implicit p: Printable[A]) =
p.contramap[Box[A]](_.value)
implicit val stringPrintable: Printable[String] =
new Printable[String] {
def format(value: String): String =
"Foo " | | value | | " Too"
}
Оба являются реализацией для типов. Вопрос в том, когда использовать def
и когда использовать val
?
Весь код:
package com.sweetsoft
import cats.instances.string._
import cats.syntax.semigroup._
import cats.Contravariant
import cats.Show
import cats.instances.string._
final case class Box[A](value: A)
trait Printable[A] {
self =>
def format(value: A): String
def contramap[B](func: B => A): Printable[B] =
new Printable[B] {
override def format(value: B): String = self.format(func(value))
}
}
object Main {
val showString = Show[String]
implicit def boxPrintable[A](implicit p: Printable[A]) =
p.contramap[Box[A]](_.value)
implicit val stringPrintable: Printable[String] =
new Printable[String] {
def format(value: String): String =
"Foo " | | value | | " Too"
}
implicit val booleanPrintable: Printable[Boolean] =
new Printable[Boolean] {
def format(value: Boolean): String =
if (value) "yes" else "no"
}
def main(args: Array[String]): Unit = {
println(format("Hello"))
//println(format(Box("hello world")))
}
def format[A](value: A)(implicit p: Printable[A]): String =
p.format(value)
}
Комментарии:
1. Здесь нет ничего
implicit
специфичного: соответствующие соображения точно такие же, какval
vs.def
в любом другом контексте.
Ответ №1:
Ваш boxPrintable
принимает параметр типа A
и аргумент значения типа Printable[A]
, поэтому это должно быть def
.
String
это один конкретный тип, поэтому stringPrintable
вообще не принимает параметров, это просто константа, поэтому вы можете определить ее как val
.
Больше ничего.
Ответ №2:
def
вычисляется при каждом запросе.
val
вычисляется при создании класса.
В вашем примере вам нужен a, def
как только у него появятся параметры, которые невозможны с val
s.