Пример взят из Финал без тегов по освоению функционального программирования:
trait Capabilities[F[_]] {
def resource(name: String): F[String]
def notify(target: String, text: String): F[Unit]
}
import cats.Monad
def income[F[_]](implicit M: Monad[F], C: Capabilities[F]): F[Unit] =
for {
contents <- C.resource("sales.csv")
total = contents
.split("\n").toList.tail // Collection of lines, drop the CSV header
.map { _.split(",").toList match // List[Double] - prices of each of the entries
{ case name :: price :: Nil => price.toDouble }
}
.sum
_ <- C.notify("[email protected]", s"Total income made today: $total")
} yield ()
Чтобы скомпилировать, я должен включить:
import cats.implicits._
Без этого я получаю ошибку:
Ошибка: (21, 27) карта значений не является членом параметра типа F [String] contents ‹- C.resource (" sales.csv ")
Два вопроса:
- Тип
F
заранее не известен. Но естьMonad
иCapabilities
определяютimplicitly
дляF
. Почему компилятор Scala не может идентифицировать его без импортирования из кошачьих. - Обычно я предпочитаю найти определенный тип и не импортирую все из
cats
. Например, точнее импортировать толькоcats.instances.list._
. Что именно используется компилятором Scala изcats.implicits._
, чтобы можно было скомпилировать этот код? И что еще более важно, какой алгоритм вы используете, чтобы его найти? - Я также обнаружил, что если я добавлю параметр
-Xprint-args
, код будет успешно скомпилирован даже без импортаcats.implicits._
. Не могли бы вы объяснить, как это влияет на это?