2017-07-13 4 views
1

私はScalaを使用して固定長を処理するライブラリを作成しています。1つの共通インポートを取得するために必要な外部implicitsをインポートするまたはimplicitsをマージする

stringsを符号化してデコードするために、私はタイプクラスベースのシステムを使用します。私はこのアクションを処理するために私自身のRead[A]Write[A]を提供しました。

私のWriteタイプのクラスはShowからCatsフードの下で使用しています。それは動作しますが、それは次のように、明示的に猫の暗黙をインポートするには、ユーザーが必要です。

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のインポートを隠したい、あるいは(可能であれば)3つすべてを1つの暗黙のオブジェクトにマージしたいと思います。

答えて

5

catsは、オブジェクトをプロバイダ自身に変換するために拡張できる特別な特性の中にある型クラスインスタンスを格納します。インスタンスはタイプ別にグループ化されていますので、Int,AnyValまたはListのすべてのインスタンスを取得できますが、「Showを持つもの」は使用できません。

ただし、注意点があります

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 

たとえば、あなたはAnyValInstancesを拡張することができますので、これは(ワークシートで)コンパイルします。 catsからインスタンスをインポートすると、曖昧であることに起因Show[Int]にコンパイルエラーが発生します。

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)) 
    } 
} 

上記コードのRunnableをバージョンはhere

利用可能です
関連する問題