导入所需的外部含义或合并含义以获得一个常见的导入

Ata*_*ais 1 scala implicit typeclass scala-cats

我正在使用Scala创建一个处理固定长度的库.

对于编码和解码,strings我使用基于类型的系统.我提供了自己的Read[A]Write[A]处理这些行动.

Write型类使用ShowCats引擎盖下.它有效,但它要求用户明确导入猫的暗示,如:

import com.github.atais.util.Read._
import cats.implicits._
import com.github.atais.util.Write._
Run Code Online (Sandbox Code Playgroud)

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

有走动吗?我想隐藏cats导入或(如果可能的话)将所有三个合并到一个隐式对象中.

Ole*_*cov 5

cats将类型实例存储在特殊特征中,您可以扩展这些特性以将对象转换为提供者本身.然而,实例按类型分组,因此您可以将所有实例用于Int,AnyVal或者List,而不是"带有任何内容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
Run Code Online (Sandbox Code Playgroud)

但是,有一个警告.导入实例cats将导致编译错误,因为Show[Int]它不明确:

import Write._
import cats.implicits._

// implicitly[Write[Int]] // this will fail to compile b/c we have Show[Int] twice
Run Code Online (Sandbox Code Playgroud)

我倾向于编写一些样板代码以避免给用户带来进口负担.

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))
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处获得上述代码的Runnable版本