2017-12-17 7 views
0

は、私は、次のしている:基本特性からの戻り子タイプに型クラスのパターンと

trait Grabber[A, B] { 
    def name: String 
    def grab(a: A): Option[B] 
} 

object Grabber { 
    implicit def toBooleanGrabber[A](s: String, f: A => Option[Boolean]) = 
    new BooleanGrabber[A] { 
     override val name: String = s 
     override def grab(a: A): Option[Boolean] = f(a) 
    } 

    implicit def toDoubleGrabber[A](s: String, f: A => Option[Double]) = 
    new DoubleGrabber[A] { 
     override val name: String = s 
     override def grab(a: A): Option[Double] = f(a) 
    } 

    implicit def toLongGrabber[A](s: String, f: A => Option[Long]) = 
    new LongGrabber[A] { 
     override val name: String = s 
     override def grab(a: A): Option[Long] = f(a) 
    } 

    def apply[A, B](
    s: String, 
    f: A => Option[B] 
)(implicit ev: (String, A => Option[B]) => Grabber[A, B]): Grabber[A, B] = 
    ev(s, f) 
} 

trait BooleanGrabber[A] extends Grabber[A, Boolean] 
trait DoubleGrabber[A] extends Grabber[A, Double] 
trait LongGrabber[A] extends Grabber[A, Long] 

apply方法が正常に動作しますが、(その明示的な定義ごとに)それはGrabber[A, B]を返します。 Grabber[A, B]の子を返すようにapplyメソッドのシグニチャを変更する方法はありますか?たとえば、toBooleanGrabberを使用する呼び出しでは、Grabber[T, Boolean]ではなく、BooleanGrabber[T]が返されるのが理想的です。

+1

なぜ具体的なタイプが必要なのですか?意味、あなたは理由のためにそれを抽象化していますが、今私は思う目的を敗北させる種類の基礎を知る必要があります。 –

答えて

2

applyメソッドに追加の型パラメータを追加できます。

def apply[A, B, R](
    s: String, 
    f: A => Option[B] 
)(implicit ev: (String, A => Option[B]) => R with Grabber[A, B]): R = 
    ev(s, f) 
+0

'R <:グラバー[A、B]'おそらく? – Dima

+0

また可能ですが、暗黙的な検索では型パラメータの境界が考慮されないため、あまり強くないと思います。 –

+0

美しい! (また、暗黙探索中の境界についての興味深い点もあります) – user451151

関連する問題