我一直在尝试遍历Scala中的数据结构并同时做两件事。为此,我一直在使用 Cats 库。这是一个无法编译的小例子。我不明白如何才能完成这项工作。非常感谢任何帮助。
import cats.data.Tuple2K
import cats.data.Const
import cats.syntax.traverse._
List("A", "BB", "CCC").traverse[Tuple2K[[x] =>> Const[Int, x], [x] =>> Const[Int, x], Nothing], Nothing]{
case str =>
Tuple2K[[x] =>> Const[Int, x], [x] =>> Const[Int, x], Nothing](Const(1), Const(str.size))
}
工具抛出以下错误:
Found: cats.data.Tuple2K[[x] =>> cats.data.Const[Int, x], [x] =>> cats.data.Const[Int, x], Nothing]
Required: cats.data.Tuple2K[[x] =>> cats.data.Const[Int, x], [x] =>> cats.data.Const[Int, x], Nothing][Nothing]
我试图获取可遍历的大小(我的示例中的上述列表)并仅在一次遍历中执行一些基于内容的计算,而不是遍历列表两次。
更新 在对我的帖子进行初步回复后,我决定通过此更新提供更多清晰度。
需要明确的是,如果我删除显式类型参数,代码将编译并执行我期望的操作:
import cats.data.Tuple2K
import cats.data.Const
import cats.syntax.traverse._
List("A", "BB", "CCC").traverse{
case str =>
Tuple2K[[x] =>> Const[Int, x], [x] =>> Const[Int, x], Nothing](Const(1), Const(str.size))
} // Tuple2K(Const(3),Const(6)) which is of type Tuple2K[[x >: Nothing <: Any] => Const[Int, x], [x >: Nothing <: Any] => Const[Int, x], List[Nothing]] !!!
我对初始代码片段的问题是,这些类型无论如何都是由编译器推断的,因此显式传递它们应该可以。
我真的不明白你为什么要尝试自己手动指定所有这些类型。类型推断的重点是避免指定这些重复且烦人的类型,并且仍然是类型安全的。
无论如何,你想要的类型签名是这样的:
List("A", "BB", "CCC").traverse[[x] =>> Tuple2K[[y] =>> Const[Int, y], [y] =>> Const[Int, y], x], Nothing] {
case str =>
Tuple2K[[x] =>> Const[Int, x], [x] =>> Const[Int, x], Nothing](Const(1), Const(str.size))
}
这是因为
traverse
需要两种类型:类型为 G[_]
的类型构造函数 * -> *
和类型为 B
的普通类型 *
。G[_]
是:
[x] =>> Tuple2K[
[y] =>> Const[Int, y],
[y] =>> Const[Int, y],
x
]
您可以在此处看到运行的代码:https://scastie.scala-lang.org/BalmungSan/byuGYrQUTaC4HvXYA8WhNw/3