簡體   English   中英

導入所需的外部隱式或合並隱式以獲取一個公共導入

[英]Importing required external implicits or merging implicits to get one common import

我正在創建一個使用Scala處理固定長度的庫。

為了對strings進行編碼和解碼,我使用基於類型類的系統。 我提供了自己的Read[A]Write[A]來處理此操作。

我的Write類型課使用引擎蓋下的Show from Cats 它可以工作,但是需要用戶顯式導入cat的隱式內容,例如:

import com.github.atais.util.Read._
import cats.implicits._
import com.github.atais.util.Write._

該示例可以在Github項目上看到:
https://github.com/atais/Fixed-Length/blob/702d7d242e5b1f6e1c6b581ad7356f36ca6ed8d9/src/test/scala/com/github/atais/fixedlength/simple/CodecTest.scala

有沒有四處走走? 我想隱藏cats導入或(如果可能)將所有三個cats合並為一個隱式對象。

cats將類型類實例存儲在特殊特征內,您可以擴展這些特征以將對象本身變成提供程序。 實例按類型分組然而,這樣你就可以采取所有實例IntAnyValList ,而不是“與任何Show ”。

例如,您可以擴展AnyValInstances ,以便將其編譯(在工作表中)

import cats.Show
import cats.instances.AnyValInstances


trait Write[A]

object Write extends AnyValInstances {
    implicit def writeForCatsShow[A](implicit s: Show[A]): Write[A] = new Write[A] { }
}

import Write._

implicitly[Write[Int]] // Show[Int] is in scope

但是,有一個警告。 由於Show[Int]含糊不清,因此從cats導入實例將導致編譯錯誤:

import Write._
import cats.implicits._

// implicitly[Write[Int]] // this will fail to compile b/c we have Show[Int] twice

我更喜歡編寫一些樣板代碼,以免完全使用戶負擔導入。

object file1 {
  // pretend it's a different file
  import cats.Show
  import cats.implicits._ 

  trait Write[A]

  object Write {

    // implement generic Show <-> Write here
    private def fromShow[A](implicit s: Show[A]): Write[A] = new Write[A] { }

    // manually create instances for types you need
    implicit val intWrite  = fromShow[Int]
    implicit val longWrite = fromShow[Long]
    implicit val doubleWrite = fromShow[Double]
    implicit val stringWrite = fromShow[String]

    // BONUS: define instances for other types that have Show
    // without causing any ambiguities
    implicit def listWrite[A](implicit wa: Write[A]): Write[List[A]] = ???
  }
}

object file2 {
  import file1.Write

  object Methods {
        def testWrite[A](a: A)(implicit write: Write[A]) = 42
    }
}

object file3 {
  import file2.Methods

  // We don't need to import cats.Show OR Write at all
  // because Show instances are resolved in object Write code
  // and Scala automatically looks up Write[A] instances in
  // companion object, so Write[Double] will be picked
  def main(args: Array[String]) = {
        println(Methods.testWrite(2.11))
    }
}

以上代碼的可運行版本在此處提供

暫無
暫無

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

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