试图通过Miles Sabin 使用这个技巧来创建一个只接受一组预定义参数的函数types.
val bool = Boolean
val timestamp = new Timestamp(date.getTime())
val str = "My String"
Run Code Online (Sandbox Code Playgroud)
然后跟随应该在编译时通过
takeValue(bool)
takeValue(timestamp)
takeValue(str)
Run Code Online (Sandbox Code Playgroud)
但
这里takeValue应该失败takeValue(someIntValue),如果implicit用于type Int不defined.And这种故障会在编译的时候.
trait MyConv[K] { type V; def convert: AnyRef => V }
def iMakeConv[V0](con: AnyRef => V0) = new MyConv[con.type] {
override type V = V0
val convert = con
}
def takeValue(value:AnyRef)(implicit conv :MyConv[value.type]) : \/[Throwable,conv.V] = \/.fromTryCatch(conv.convert(value))
Run Code Online (Sandbox Code Playgroud)
然后
implicit val strAny = iMakeConv((x:Any) => x.toString)
Run Code Online (Sandbox Code Playgroud)
然后我想takeValue(str)在编译时工作,但在编译时takeValue(someIntValue)失败,因为没有任何适当的implicit定义.基本上想要限制(在编译时)类型types takeValue可以接受和失败的其他人.
当然,我在这里做错了,因为在打电话时
takeValue("string")
Run Code Online (Sandbox Code Playgroud)
它在编译时抛出
could not find implicit value for parameter conv:
MyConv[String("string")]
- not enough arguments for method takeValue: (implicit conv:
MyConv[String("string")])scalaz.\/[Throwable,conv.V].
Unspecified value parameter conv.
Run Code Online (Sandbox Code Playgroud)
意思.type经常被误解.类型value.type是只有一个值的类型 - value.即使value已知String,value.type不是String,但具体只有一个String- value.
结果,MyConv[value.type]即使有MyConv[String]可用代码,代码也会尝试查找不存在的代码.
请takeValue改用类型参数:
def takeValue[T](value: T)(implicit conv: MyConv[T]) : \/[Throwable, conv.V] = \/.fromTryCatch(conv.convert(value))
Run Code Online (Sandbox Code Playgroud)
或者,也可以制作MyConv 逆变的类型参数:
trait MyConv[-K] { type V; def convert: AnyRef => V }
Run Code Online (Sandbox Code Playgroud)
MyConv[T]如果value.type是子类型,则允许使用a T.
您还需要一个不同的MyConv和iMakeConv:
trait MyConv[K] { type V; def convert: K => V }
def iMakeConv[K, V0](con: K => V0) = new MyConv[K] {
override type V = V0
val convert = con
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
76 次 |
| 最近记录: |