2017-08-06 24 views
0

我有一個自定義類型,Value內部U型依賴特質高清

trait Value 
object Value { 
    case class BooleanValue(record: Boolean) extends Value 
    case class LongValue(record: Long) extends Value 
} 

而且知道如何得到Value一個特點,叫GetsValue,給予一定的輸入型T

sealed trait GetsValue[T] { def apply(record: T): Option[Value] } 
object GetsValue { 
    trait GetsBooleanValue[T] extends GetsValue[T] { override def apply(record: T): Option[Value.BooleanValue] } 
    trait GetsLongValue[T] extends GetsValue[T] { override def apply(record: T): Option[Value.LongValue] } 
} 

請注意,GetsValue是密封的,所以用戶只能擴展GetsValue.GetsBooleanValueGetsValue.GetsLongValue

trait Extractor[T] { 
    def title: String 
    def getsValue: GetsValue[T] 
    def relatedValue[U]: U = ??? // question below 
} 

我想實現的是以下幾點:

如果getsValueGetsValue.GetsBooleanValue[_],然後返回與文本String 「噓!」 (即,UString類型)。

如果getsValueGetsValue.GetsLongValue[_],然後用1.1的值(即,UDouble類型的)返回一個Double

另請注意,我不想匹配getsValue的類型T。無論T是什麼類型,我都想匹配。

我想使用類型類/ implicits,如果這是有道理的。 使用Either不適合我。

+0

我不認爲這會工作,你可以有一個包裝的雙/字符串,雖然使用路徑依賴類型。 –

回答

2

也許類似這樣的工作:

首先,修改GetsValue添加指定的返回類型的類型參數:

sealed trait GetsValue[T, V <: Value] { def apply(record: T): Option[V] } 
object GetsValue { 
    trait GetsBooleanValue[T] extends GetsValue[T, Value.BooleanValue] { } 
    trait GetsLongValue[T] extends GetsValue[T, Value.LongValue] { } 
} 

然後性狀的類型V到的價值關聯U

trait RelatedValue[V <: Value, U] { 
    def get: U 
} 

還有一些這種性狀的隱含值:

object Extractor { 
    implicit val boolRV = new RelatedValue[Value.BooleanValue, String] { def get = "boo!" } 
    implicit val longRV = new RelatedValue[Value.LongValue, Double] { def get = 1.1 } 
} 

那麼你提取性狀可以是:

trait Extractor[T] { 
    type V <: Value 
    type U 
    def title: String 
    def getsValue: GetsValue[T, V] 
    def relatedValue(implicit rv: RelatedValue[V, U]): U = rv.get 
} 

的範例:

object Example extends Extractor[String] { 
    type V = Value.BooleanValue 
    type U = String 
    def title = "Example" 
    def getsValue = new GetsValue.GetsBooleanValue[String] { 
    def apply(s: String) = None 
    } 
} 

import Extractor._ 
println(Example.relatedValue) 

打印 「噓!」