Scala: «Обобщение» по синглтон-типам? - PullRequest
0 голосов
/ 08 июня 2018

В Scala значения и объекты имеют одноэлементные типы, назначаемые им индивидуально.Таким образом, мы можем иметь:

val x = 1
type X = x.type
val y = 2
type Y = y.type
  • Могу ли я написать метод, который принимает в качестве аргумента только x?

Я пытался:

val x = 1
def foo(i: x.type ) = println(x.toString)

, но это дает мне ошибку.Я думаю, что это жалуется на тот факт, что тип неизвестен.Есть ли способ указать тот факт, что i, как ожидается, будет int, чтобы мы могли использовать, скажем, .tofloat для него?

  • Do X и Yвыше, а именно синглетные типы 1 & 2, имеют общего предка, поэтому я могу написать общий код, который включает в себя синглтонный тип, скажем, Int значения.

  • Точно так же,

, если бы у меня было, например,

 val list = [1,2,3]

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

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Я пишу метод, который принимает только x в качестве аргумента?

Если он может принимать только один параметр, тогда ему не нужно

val x = 1
def f() = println(x.toString)

Делать X и Y выше, а именно одиночные типы 1 и 2У меня есть общий предок, так что я могу написать общий код, который включает в себя синглтонный тип, скажем, Int значения ...

Я не понимаю.Один из способов получить функцию, которая принимает набор произвольных классов в качестве входных данных, - это использовать неявное преобразование

trait CanUse{
    def use(): Int
}

def f[A](a: A)(implicit cvt: (A) => CanUse): Int = cvt(a).use() + 1

, а затем определить неявное преобразование для каждого допустимого типа ввода

implicit class UsableInt(i: Int) extends CanUse{
   def use() = i
}
0 голосов
/ 08 июня 2018

В 2.12.5 он работает только для не примитивных целых чисел в штучной упаковке:

val x: java.lang.Integer = 42
def foo(i: x.type): Unit = println(i.toFloat)

Хотя я не знаю, почему это не работает для val x: Int.В Dotty это работает также для примитивных типов:

val x: Int = 42
def foo(i: x.type): Unit = println(x.toFloat)

Для более чем одного значения (списка) вы можете взять перечисление или просто создать небольшой класс с закрытым конструктором и создать все допустимые значениявнутри класса-компаньона:

class SmallInt private(value: Int) {
  def asFloat = value.toFloat
}

object SmallInt {
  val one = new SmallInt(1)
  val two = new SmallInt(2)
  val three = new SmallInt(3)
}

это не скомпилируется тогда:

val foo = new SmallInt(345678) // forbidden
...