2017-02-02 9 views
2

シェイプレスを使用すると暗黙の順序が問題になるようです。 以下のサンプルコードを参考にしてください。暗黙のメソッドの順序付けとシェイプレスによるマッピング

import shapeless._ 

case class Userz(i: Int, j: String, k: Option[Boolean]) 

object r { 
    def func(): Userz = { 
    val a = Userz(100, "UserA", Some(false)) 
    val b = Userz(400, "UserB", None) 

    val genA = Generic[Userz].to(a) 
    val genB = Generic[Userz].to(b) 

    val genC = genA zip genB 

    val genD = genC.map(Mergerz) 
    val User = Generic[Userz].from(genD) 
    return User 
    } 
} 
object Mergerz extends Poly1 { 
    implicit def caseInt = at[(Int, Int)] {a => a._1 + a._2} 
    implicit def caseString = at[(String, String)] {a => a._1 + a._2} 
    implicit def caseBoolean = at[(Option[Boolean], Option[Boolean])] {a => Some(a._1.getOrElse(a._2.getOrElse(false)))} 
} 

r.func() 

、コードはこれを下回る動作します

import shapeless._ 

case class Userz(i: Int, j: String, k: Option[Boolean]) 

object Mergerz extends Poly1 { 
    implicit def caseInt = at[(Int, Int)] {a => a._1 + a._2} 
    implicit def caseString = at[(String, String)] {a => a._1 + a._2} 
    implicit def caseBoolean = at[(Option[Boolean], Option[Boolean])] {a => Some(a._1.getOrElse(a._2.getOrElse(false)))} 
} 

object r { 
    def func(): Userz = { 
    val a = Userz(100, "UserA", Some(false)) 
    val b = Userz(400, "UserB", None) 

    val genA = Generic[Userz].to(a) 
    val genB = Generic[Userz].to(b) 

    val genC = genA zip genB 

    val genD = genC.map(Mergerz) 
    val User = Generic[Userz].from(genD) 
    return User 
    } 
} 


r.func() 

私の質問は、なぜ注文事項をしているのですか?私はすでに働かない暗黙のものをインポートしようとしました。

答えて

1

ファイル内の型推論は、基本的に上から下に働くためです。型式がfuncの場合、caseIntには届かず、適切かどうかはわかりません。注釈の種類にも注釈を付ける必要がありますが、一般的には暗黙的に推奨されますが、Shapelessのようなライブラリを使用すると問題が発生する可能性があります。例についてはShapeless not finding implicits in test, but can in REPLを参照してください。

+1

シェイプレスで作業するときは、暗黙の定義に注釈を付けることを常にお勧めします。かなり珍しい状況がいくつかありますが、これは厄介なものですが、大部分は可能であり、望ましいものです。 –

+0

@MilesSabinご清聴ありがとう! –

関連する問題