[英]Importing required external implicits or merging implicits to get one common import
I am creating a library to handle fixed-length using Scala. 我正在创建一个使用Scala处理固定长度的库。
For encoding and decoding the strings
I use type class based system. 为了对strings
进行编码和解码,我使用基于类型类的系统。 I have provided my own Read[A]
and Write[A]
for handling this actions. 我提供了自己的Read[A]
和Write[A]
来处理此操作。
My Write
type class is using Show
from Cats
under the hood. 我的Write
类型课使用引擎盖下的Show
from Cats
。 It works, but it requires the user to explicitly import cats' implicits, like: 它可以工作,但是需要用户显式导入cat的隐式内容,例如:
import com.github.atais.util.Read._
import cats.implicits._
import com.github.atais.util.Write._
the example could be seen on the Github project: 该示例可以在Github项目上看到:
https://github.com/atais/Fixed-Length/blob/702d7d242e5b1f6e1c6b581ad7356f36ca6ed8d9/src/test/scala/com/github/atais/fixedlength/simple/CodecTest.scala https://github.com/atais/Fixed-Length/blob/702d7d242e5b1f6e1c6b581ad7356f36ca6ed8d9/src/test/scala/com/github/atais/fixedlength/simple/CodecTest.scala
Is there any walk-around? 有没有四处走走? I would like to hide the cats
import or (if possible) merge all three into a single implicit object. 我想隐藏cats
导入或(如果可能)将所有三个cats
合并为一个隐式对象。
cats
stores typeclass instances inside special traits that you can extend to turn your objects into providers themselves. cats
将类型类实例存储在特殊特征内,您可以扩展这些特征以将对象本身变成提供程序。 Instances are grouped by type however, so you can take all instances for Int
, AnyVal
or List
, but not "anything with Show
". 实例按类型分组然而,这样你就可以采取所有实例Int
, AnyVal
或List
,而不是“与任何Show
”。
For example, you can extend AnyValInstances
, so this will compile (in a worksheet) 例如,您可以扩展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
There is a caveat, however. 但是,有一个警告。 Importing instances from cats
will cause compilation error due to Show[Int]
being ambiguous: 由于Show[Int]
含糊不清,因此从cats
导入实例将导致编译错误:
import Write._
import cats.implicits._
// implicitly[Write[Int]] // this will fail to compile b/c we have Show[Int] twice
My preference would be to write some boilerplate code to avoid burdening users with imports at all. 我更喜欢编写一些样板代码,以免完全使用户负担导入。
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))
}
}
Runnable version of above code is available here 以上代码的可运行版本在此处提供
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.