Scala:" Genericising"单身人士类型?

时间:2018-06-08 13:04:55

标签: scala types type-level-computation singleton-type

在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

  • 上面的XY,即1&的单身类型2,有一个共同的祖先,所以我可以写一个涉及单Int个值的通用代码。

  • 类似地,

如果我有例如

 val list = [1,2,3]

有没有一种编写代码的方法,这些代码可以通过这些代码进行泛化,只能输入其中一个值?

2 个答案:

答案 0 :(得分:1)

在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

答案 1 :(得分:1)

  

我写了一个只接受x作为参数的方法?

如果它只能采用一个参数,那么它就不需要

@override
void initState() {}
  

上面的X和Y,即1和1的单例类型。 2,有一个共同的祖先,所以我可以编写一个通用代码,涉及单个类型的说Int值......

我不明白。有一个函数的一种方法是使用一组任意类作为输入,使用隐式转换

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

然后为每个可接受的输入类型定义隐式转换器

trait CanUse{
    def use(): Int
}

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