簡體   English   中英

使用Scala-cats隱式解決

[英]Implicits resolution with Scala-cats

示例摘自Mastering Functional Programming中的Tagless Final

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("admin@shop.com", s"Total income made today: $total")
  } yield ()

為了進行編譯,我必須包括:

import cats.implicits._

沒有這個,我會得到一個錯誤:

錯誤:(21,27)值映射不是類型參數F [String]內容的成員<-C.resource(“ sales.csv”)

兩個問題:

  1. F類型事先未知。 但是有MonadCapabilitiesF implicitly定義。 為什么Scala編譯器在沒有從cats隱式導入的情況下無法識別它。
  2. 通常,我更喜歡找到某種類型的東西,而不是從cats進口所有東西。 例如,更准確地說,僅導入cats.instances.list._ 為了能夠編譯此代碼,Scala編譯器從cats.implicits._到底使用了什么? 更重要的是,您使用什么算法來找到它?
  3. 我還發現,如果添加-Xprint-args選項,即使沒有cats.implicits._導入,代碼也可以成功編譯。 您能解釋一下,它如何影響它?
  1. 沒有隱式導入,Scala編譯器無法識別的僅僅是語法。 實例可以正確解析而無需導入(由於隱式參數)。

  2. cats.implicits._您實際上只使用

     import cats.syntax.functor._ import cats.syntax.flatMap._ 
  3. https://github.com/scala/scala/pull/5909

    該選項的行為類似於-Xshow-phases並在打印后停止編譯器


沒有導入語法,您可以編寫

def income[F[_]](implicit M: Monad[F], C: Capabilities[F]): F[Unit] =
  M.flatMap(C.resource("sales.csv"))(contents => {
    val 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
    M.map(C.notify("admin@shop.com", s"Total income made today: $total"))(_ => ())
  })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM