В Scala возможно ли получить `val`, на который ссылается тип singleton? - PullRequest
4 голосов
/ 08 сентября 2011

Я пытаюсь получить минимальную форму зависимых типов в Scala.Если у меня есть

class A[T <: Int]

val x: Int = 7

, я могу

val a = new A[x.type]

Теперь возможно ли восстановить x из его синглтона x.type?

Или, если это не таквозможно, возможно ли как-то связать стабильный идентификатор с типом, а затем извлечь его?

Ответы [ 2 ]

6 голосов
/ 08 сентября 2011

Нет, вы не можете восстановить x из x.type из-за удаления типа JVM.Например, как это будет реализовано?

def f[A]: A = ???
f[x.type]

На уровне байт-кода JVM нет способа, чтобы f мог найти значение x: A, данное A = x.type, потому что у него ничего не работаетwith: все параметры типа теряются во время выполнения, и в любом случае значение x недоступно в стеке параметров f.

По той же причине для получения стабильного идентификаторатип, вы должны будете изменить его как Manifest значение.Но когда я пытался, я получаю странный результат:

def f[A : Manifest] = implicitly[Manifest[A]]
val x = "hi"
val y = "ho"
println(f[x.type]) // hi.type
println(f[y.type]) // ho.type
f[x.type] == f[y.type] // true !?

Я не уверен, почему эти два манифеста типа равны - они даже имеют разные представления toString.Может ли это быть ошибкой Scala? Обновление : в соответствии с ScalaDoc , операторы отношения типов <: <и =: = должны рассматриваться только как приблизительные, поскольку существует множество аспектов соответствия типов, которыееще недостаточно представлен в манифестах. </em>

Подводя итог, можно сказать, что преобразование информации о типе в значения времени выполнения не происходит автоматически в JVM.Скала Manifest должна заполнить пробел, но я думаю, она не работает с зависимыми типами.

3 голосов
/ 08 сентября 2011

Чтобы ответить на ваш второй вопрос, «связать стабильный идентификатор с типом», один из способов сделать это - использовать классы типов. Допустим, я хочу связать описание строки с типами, я могу сделать это следующим образом:

trait Tag[A] {
  val desc : String
}

implicit object StringTag extends Tag[String] {
  val desc = "character string"
}

implicit object IntTag extends Tag[Int] {
  val desc = "32-bit integer"
}

Теперь, чтобы восстановить такие теги, введите неявную магию:

def printTag[T : Tag] {
  val tag = implicitly[Tag[T]]
  println("Type is described as : " + tag.desc)
}

например:

printTag[String] // prints "Type is described as : character string"
printTag[Double] // compile-time error: no implicit value found of type Tag[Double]

Вы даже можете создавать теги по мере необходимости, используя неявные функции. Например:

implicit def liftTagToList[T : Tag] = new Tag[List[T]] {
  val underlying = implicitly[Tag[T]].desc
  val desc = "list of " + underlying + "s"
}

Теперь я могу сделать следующее:

// prints "Type is described as : list of character strings"
printTag[List[String]]

и даже:

// prints "Type is described as : list of list of character stringss"
printTag[List[List[String]]]

Пожалуйста, прости множественное число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...