В Scala можно получить «Val», на который ссылается тип синглтона?

StackOverflow https://stackoverflow.com/questions/7343163

  •  27-10-2019
  •  | 
  •  

Вопрос

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

class A[T <: Int]

val x: Int = 7

Я могу

val a = new A[x.type]

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

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

Это было полезно?

Решение

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

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

На уровне байт -кодов JVM нет никакого способа f может найти ценность x: A данный A = x.type Потому что ему нечего работать: все параметры типа теряются во время выполнения, и в любом случае, 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, Операторы типового режима <: <и =: = = должны рассматриваться только приближения, поскольку существуют множество аспектов соответствия типа, которые еще не представлены в манифестах.

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

Другие советы

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

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]]]

Пожалуйста, простите плюрализацию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top