Я хотел бы указать значение типа с абстрактным типом для класса, а затем использовать его зависимый от пути тип. Посмотрите на следующий пример (с помощью Scala 2.10.1):Path-Dependent type внутри значения класса в Scala
trait Foo {
type A
def makeA: A
def useA(a: A): Unit
}
object Test {
class IntFoo extends Foo {
type A = Int
def makeA = 1
def useA(a: Int) = println(a)
}
class FooWrap(val a: Foo) {
def wrapUse(v: a.A) = a.useA(v)
}
val foo = new IntFoo
/* Path dependent locally */
val bar = foo
bar.useA(foo.makeA) // works
/* Path dependent through class value */
val fooWrap = new FooWrap(foo)
fooWrap.a.useA(foo.makeA) // fails
// error: type mismatch; found : Int required: Test.fooWrap.a.A
fooWrap.wrapUse(foo.makeA) // fails
// error: type mismatch; found : Int required: Test.fooWrap.a.A
}
Во-первых, я не понимаю, принципиальное различие между локальными и случае класс-значение (обратите внимание общественности, неизменное значение) и почему тип проверка не выполняется (потому что, очевидно, Test.fooWrap.a.A =:= foo.A
). Является ли это ограничением компилятора Scala?
Во-вторых, как я могу достичь того, что я пытаюсь сделать?
UPDATE
кажется, что это может быть достигнуто за счет использования генериков и встроенные типовые ограничения:
class FooWrap[T](val a: Foo { type A = T }) {
def wrapUse(v: T) = a.useA(v)
}
Однако, в моем случае, A
на самом деле выше-kinded типа, так пример будет следующим:
trait Foo {
type A[T]
def makeA[T]: A[T]
def useA(a: A[_]): Unit
}
object Test {
class OptFoo extends Foo {
type A[T] = Option[T]
def makeA[T] = None
def useA(a: A[_]) = println(a.get)
}
class FooWrap(val a: Foo) {
def wrapUse(v: a.A[_]) = a.useA(v)
}
val foo = new OptFoo
/* Path dependent locally (snip) */
/* Path dependent through class value */
val fooWrap = new FooWrap(foo)
fooWrap.a.useA(foo.makeA) // fails
// polymorphic expression cannot be instantiated to expected type;
// found : [T]None.type required: Test.fooWrap.a.A[_]
fooWrap.wrapUse(foo.makeA) // fails
// polymorphic expression cannot be instantiated to expected type;
// found : [T]None.type required: Test.fooWrap.a.A[_]
}
Возможный дубликат http://stackoverflow.com/questions/14544269/scala-immutability-and-path-dependent -типа совместимость – gzm0