gpt4 book ai didi

Scala 方法和更高种类的类型参数

转载 作者:行者123 更新时间:2023-12-05 00:45:43 24 4
gpt4 key购买 nike

我正在尝试在 scala 中定义一个采用 S[_] <: Seq[Double] 泛型类型的方法并返回一个 S[FixedLoad](FixedLoad 是一个具体类型)。但是我的实现给了我错误,我不知道为什么。尽管我已经尝试了很多次来理解参数类型和更高类型的类型,但我的知识增长如此缓慢。

我想要实现的是不丢失 S 的具体类型(序列子类型)。

这是代码:

import scala.collection.generic.CanBuildFrom

class FixedLoad(val id: Int, val positionInT: Int, val amplitude: Double) {
override def toString: String = s"FixedLoad($id, $positionInT, $amplitude)"
}

object Load {

implicit def toFixedLoads[S[_] <: Seq[Double]](l: S[Double])(implicit cbf: CanBuildFrom[Nothing, FixedLoad, S[FixedLoad]]): S[FixedLoad] = {
l.map(_ => new FixedLoad(1, 1, 1)).to[S]
}

def main(args: Array[String]): Unit = {
println(toFixedLoads(List(1.0, 2.0, 3.0)))
}

}

和错误:
Error:(16, 13) inferred type arguments [List] do not conform to method toFixedLoads's type parameter bounds [S[_] <: Seq[Double]]
println(toFixedLoads(List(1.0, 2.0, 3.0)))

Error:(16, 30) type mismatch;
found : List[Double]
required: S[Double]
println(toFixedLoads(List(1.0, 2.0, 3.0)))

最佳答案

简短回答:

更改toFixedLoads[S[_] <: Seq[Double]]toFixedLoads[S[A] <: Seq[A]]
长答案:

当你说 S[_] , 那是一种高级的类型。或者,换句话说,它是一个类型构造函数。这意味着它需要一个类型来产生最终的正确类型。这里有些例子:

  • List - 采用类型,例如Int , 生成正确的类型 List[Int]
  • Option - 采用类型,例如Int , 生成正确的类型 Option[Int]

  • 等等

    这种类型的构造函数通常表示为 * -> * .您提供一种类型,然后返回一种类型。还有其他种类;例如, MapEither需要两种类型来生成正确的类型(例如 Map[Int, String]Either[Error, Foo] ),所以它们的类型是 * -> * -> * .把它想象成一个柯里化(Currying)类型的构造函数;接受一个类型并返回一个接受一个类型的函数,然后你得到最终的正确类型。或者换句话说,需要两种类型来生成最终的正确类型。您可能还有一个类型构造函数,它需要一个类型构造函数来构建正确的类型(例如 Monad[F[_]] ),在这种情况下,类型是 (* -> *) -> * (例如, List -> Monad[List])。

    因此,当您说您的方法需要 S[Double] 类型的参数时你通过 List(1.0, 2.0, 3.0) , 编译器推断 S成为 List ,它提示 List[A]不是 Seq[Double] 的子类型对于任何 A .您第一次尝试解决此问题可能是 F[_] <: Seq[_] ,但这无法编译,因为内部类型仍然不对齐。我们需要用 F[A] <: Seq[A] for some A 之类的东西“连接”它们。 , 可以简单地写成 F[A] <: Seq[A] .

    一个很好的问题可能是“我可以说 S <: Seq[Double] 吗?”当然, S代表一个正确的类型,所以你完全可以!像这样的东西很好用:
    def foo[S <: Seq[Double]](s: S) = println(s)
    foo(List(1.0, 2.0)) // prints List(1.0, 2.0)

    当然,您的 S其中有一个“洞”,因为您的方法参数是 S[Double] 类型,所以它不适用于您的情况。

    关于Scala 方法和更高种类的类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56240426/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com