繁体   English   中英

在Scala中约束更高层次的类型

[英]Constraining Higher-Kinded Types in Scala

说我有更高的kinded类型

SuperMap[Key[_],Value[_]]`.  

假设我现在有一些更具体的东西,要求Key的type参数必须与Value匹配; 就是这样的:

SuperDuperMap[T, Key[T], Value[T]]

进一步假设我不想要任何T ,而是一个非常具体的T <: OtherT

SuperDuperPooperMap[T <: OtherT, Key[T], Value[T]]

这可以在Scala中完成吗? 这通常是一个坏主意吗? 有没有一种相同的方法可以更容易地读/写/使用?

你的声明已经按照预期的方式工作,即你限制了T的类型以及KeyValue 然而,如果你发布类似的东西,scala会抱怨你的方式

scala> class Foo[T <: OtherT, Key[T], Value[T]]
defined class Foo

scala> new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]]
<console>:13: error: Key[SpecialOtherT] takes no type parameters, expected: one
              new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]]

因为您的前声明已经给出了KeyValue的类型。 因此,这将有效

scala> new Foo[SpecialOtherT, Key, Value]
res20: Foo[SpecialOtherT,Key,Value] = Foo@3dc6a6fd

这可能不是你想要的。 你可以这样做

scala> class Foo[T <: OtherT, K <: Key[T], V <: Value[T]]
defined class Foo

scala> new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]]
res21: Foo[SpecialOtherT,Key[SpecialOtherT],Value[SpecialOtherT]] = Foo@7110506e

在底线,由于KeyValue的类型完全取决于T因此在使用Foo时获得所有冗余信息有点多余。 那么为什么不使用这样的内部类型声明:

class Foo[T <: OtherT] {
  type K = Key[T]
  type V = Value[T]
}

然后,您可以从类中访问类型KV ,但每次创建新答案时都不需要键入它:

scala> new Foo[SpecialOtherT]
res23: Foo[SpecialOtherT] = Foo@17055e90

scala> new Foo[Int]
<console>:11: error: ...

这可以在Scala中完成吗?

你什么意思? 你刚才做到了!

这通常是一个坏主意吗?

为什么会这样? 事实上,这是一个好主意! 这就是高等级的类型。

有没有一种相同的方法可以更容易地读/写/使用?

阅读 - 对我来说很好看。

- 写/测试/编译一次,到处使用。

使用 - 编译器将重建(推断)“无处不在”的类型。

您可能不需要比几个类型别名更复杂的东西,

type SuperDuperMap[T, Key[_], Value[_]] = SuperMap[Key, Value]

type SuperDuperPooperMap[T <: OtherT, Key[_], Value[_]] = SuperMap[Key, Value]

示例REPL会话,

scala> new SuperDuperMap[Int, Option, List] {}
res0: java.lang.Object with SuperDuperMap[Int,Option,List] = ...

scala> new SuperDuperPooperMap[OtherT, Option, List] {}
res1: java.lang.Object with SuperDuperPooperMap[OtherT,Option,List] = ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM