【问题标题】:Scala Generics, which of these 4 generic version is specific to which particular problemScala Generics,这 4 个通用版本中的哪一个特定于哪个特定问题
【发布时间】:2018-11-18 10:40:33
【问题描述】:

这四个版本可以编译,但我很好奇我们应该更喜欢一个选项而不是另一个选项的上下文。

// 1
def f[N, S <: Seq[N]](s: S)
// 2
def f[N, S[N] <: Seq[N]](s: S[N])

当使用 1 而不是 2 时,它们非常相似

2 强制 SN 作为通用参数作为 1 但这两者之间有什么区别?

然后我们有更通用的设置。

// 3
def f[N, S[X] <: Seq[X]](s: S[N])
// 3.a
def f[N, S[X] <: Seq[X]](s: S[N]): S[Int]

据我谦虚理解3 授权提取通用容器类型以供以后重用并获得类似3.a 的内容。

但是未声明的 X 泛型参数是什么意思,我想这是一种声明特殊内容的方式,但我不明白。

// 4
def f[N, S[X] <: Seq[_]](s: S[N])

除了我知道Seq[_]代表Seq[Any]之外,我不知道该说什么4

最后,我只是想了解更多关于这些工具及其特性的信息,以便更妥善地完成工作。

【问题讨论】:

    标签: scala generics higher-kinded-types


    【解决方案1】:
    // 2
    def f[N, S[N] <: Seq[N]](s: S[N])
    

    这里的想法是,S[N] &lt;: Seq[N]中提到的第一个N参数和N是完全独立的参数。他们只是共享同一个名字。

    S[N] 中提到的N 仅在其绑定的&lt;: Seq[N] 范围内可见。 参数定义中使用的N (s: S[N]) 来自第一个N,因为这是参数类型定义中唯一可见的N 参数。因此,您可以使用任何字母代替S[N] &lt;: Seq[N] 中的N,这不会以任何方式影响您的参数类型。

    // 4
    def f[N, S[X] <: Seq[_]](s: S[N])
    

    这里你只是忽略了X参数。

    编辑: 正如@alexey-romanov 在评论中提到的那样。 S[X] &lt;: Seq[X]S[X] &lt;: Seq[_]是有区别的

    这是一个显示差异的示例:

    def f1[N, S[X] <: Seq[X]](s: S[N]) = ""
    
    def f2[N, S[X] <: Seq[_]](s: S[N]) = ""
    
    type Foo[A] = Seq[Int]
    
    val foo: Foo[String] = Seq(2,3)
    
    //f1(foo) -- compilation error
    f2(foo)
    

    这里的问题是,由于类型约束器是一种“类型上的函数”,我们可以定义这样的“函数”,接受一个类型作为参数,但返回由另一个参数参数化的类型,与类型构造函数中使用的参数无关。 (见Foo

    foo val 传递给f2 很好,因为X 被推断为String,而Foo[String]Seq[Int] 的“子类型”(实际上它们是相等的),但是当我们将foo 传递给f1 X 仍然是 StringFoo[String] 不是 Seq[String] 的“子类型”(因为 Foo[String]==Seq[Int] 不是 Seq[String] 的子类型)

    // 1
    def f[N, S <: Seq[N]](s: S)
    

    在这里你说Seq[N]中使用的N与第一个参数N相同。所以这是一样的N

    【讨论】:

    • 好的,23 完全一样,只是命名的问题,谢谢!但是34 有什么区别呢?
    • 没有区别。在这两种情况下,您只是说可以有任何类型而不是X。在 3 中,您在 &lt;: Seq[X] 中使用了 X,没有任何额外限制,因此这与 _ 相同
    • @KyBe 我已经编辑了答案,以便为这种情况提供一些解释。
    • 编辑后的答案仍然有点不正确:_ 未推断为IntSeq[_] 是存在类型,Seq[Int]Seq[_] 的子类型。
    • 由于协方差,它们是等价的。
    猜你喜欢
    • 2021-04-19
    • 2017-10-06
    • 1970-01-01
    • 2021-01-25
    • 2021-07-12
    • 2016-12-26
    • 2018-06-15
    • 1970-01-01
    • 2020-04-19
    相关资源
    最近更新 更多