我正在阅读斯卡拉之旅:抽象类型.什么时候使用抽象类型更好?
例如,
abstract class Buffer {
type T
val element: T
}
Run Code Online (Sandbox Code Playgroud)
而是那些泛型,例如,
abstract class Buffer[T] {
val element: T
}
Run Code Online (Sandbox Code Playgroud) 当我阅读Liftweb的源代码时,我发现了一些特征声明:
trait ValueHolder {
type ValueType
def get: ValueType
}
trait PValueHolder[T] extends ValueHolder {
type ValueType = T
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,对于以下两个特征声明:
trait ValueHolder {
type ValueType
}
trait ValueHolder[T] {
}
Run Code Online (Sandbox Code Playgroud)
我认为它们彼此相同,但它们之间有什么区别吗?一个人可以做或提供另一个人不能做的事情吗?
据我了解,依赖类型允许您不指定输出类型:
例如,如果您有一个类型类:
trait Last[In] {
type Out
}
Run Code Online (Sandbox Code Playgroud)
那么你可以在不指定输出类型的情况下召唤一个实例:
implicitly(Last[String :: Int :: HNil]) // output type calculated as Int
Run Code Online (Sandbox Code Playgroud)
Aux 模式允许您再次指定输出类型:
implicitly(Last.Aux[String :: Int :: HNil, Int])
Run Code Online (Sandbox Code Playgroud)
您需要在隐式参数列表中使用它,以便对输出类型做一些有用的事情(解决 Scala 对依赖类型的限制)。
但是如果你总是需要指定(或分配一个类型参数)输出类型,为什么首先要使用依赖类型(然后是 Aux)呢?
我尝试Last
从 Shapeless 的 src复制类型类,替换type Out
为特征中的附加类型参数并删除 Aux。它仍然有效。
当我真正需要它们时是什么情况?