Можем ли мы использовать синглтон .type в качестве параметра типа?

Я собирал ответ на этот вопрос: Scala mixin to class instance, где я показал способ «примешивания» другого признака или экземпляра класса к существующему экземпляру:

case class Person(name: String)
val dave = Person("Dave")
val joe  = Person("Joe")

trait Dog { val dogName: String }
val spot = new Dog { val dogName = "Spot" }

implicit def daveHasDog(p: dave.type) = spot

dave.dogName //"Spot"
joe.dogName  //error: value dogName is not a member of Person

Таким образом, после локального неявного определения dave можно эффективно использовать как Person with Dog. Мой вопрос: если мы хотим определить метод, который принимает экземпляр Person только там, где Person имеет Dog, как нам это сделать?

Я могу определить такой метод, как

def showDog(pd: Person with Dog) = pd.name + " shows " + pd.dogName

однако это не годится для dave, поскольку он все еще всего лишь Person, несмотря на его неявные способности к трансформации.

Я пытался определить

trait Dog [T] { val dogName: String }
val spot = new Dog [dave.type] { val dogName = "Spot" }
def showDog(p: Person)(implicit dog: Dog[p.type]) = ...

но это не законно, давать error: illegal dependent method type. Любые идеи?


person Luigi Plinge    schedule 17.04.2012    source источник


Ответы (1)


Если вы скомпилируете с -Ydependent-method-types, исходный код будет работать с этим определением showDog:

scala> def showDog(p: Person)(implicit ev: p.type => Dog) = p.name + " shows " + p.dogName
showDog: (p: Person)(implicit ev: p.type => Dog)java.lang.String

scala> showDog(dave)
res1: java.lang.String = Dave shows Spot
person Destin    schedule 17.04.2012
comment
Просто для ясности: для этого требуются зависимые типы, потому что тип ev зависит от значения p. Я очень удивлен и впечатлен тем, что в Scala даже есть опция компилятора для этого. - person Dan Burton; 18.04.2012
comment
@Dan Было бы еще лучше, если бы он был включен по умолчанию. - person ziggystar; 18.04.2012
comment
@ziggystar: я думаю, что это будет включено в версии 2.10. (На самом деле от этого зависит система макросов и отражений.) - person Debilski; 18.04.2012
comment
@Debilski это уже включено в последних вехах 2.10. - person Miles Sabin; 19.04.2012