gpt4 book ai didi

scala - 推断常见的父类(super class)型

转载 作者:行者123 更新时间:2023-12-04 17:53:30 28 4
gpt4 key购买 nike

这是我想要做的

  def merge[A, B, C](eithers: Either[A,B]*)(implicit ev1: A <:< C, ev2: B <:< C): Seq[C] =
eithers.flatMap(_.fold(Option[C](_), Option[C](_)))

基本上,我想“展平” Either[A,B] 的列表变成 Seq[C] ,其中 C 是 A 和 B 的常见父类(super class)型(显然 Any 除外)。

例如:
  trait Foo
class Bar extends Foo
class Baz extends Foo

merge(Left[Bar, Baz](new Bar), Right[Bar, Baz](new Baz))

这不起作用:(
它说 Cannot prove that Baz <:< C
但是,这确实有效:
  merge[Bar, Baz, Foo](Left[Bar, Baz](new Bar), Right[Bar, Baz](new Baz))
res7: Seq[Foo] = ArrayBuffer(Bar@613f7eb7, Baz@565aa4ac)

所以,问题是有人可以用某种技巧让它推断出普通的父类(super class)型,这样我就不必像这样拼出来了吗?
或者,至少,一种只使用一个类型参数的方法(我不介意指定结果的类型,因为我必须拼出传入数据的类型)。

我知道做后者的一种方法是将它分配给一个变量:
val merged: Seq[Foo] = merge(Left[Bar, Baz](new Bar), Right[Bar, Baz](new Baz)) 

这行得通,但对我来说不太合适,因为我讨厌声明只使用一次的变量。理想情况下,我希望做这样的事情:
merge(input)
.filter(doILikeIt)
.map(doSomethingInteresting)
// etc.

有任何想法吗?

最佳答案

有一个简单的解决方案,使用方差:

def merge[C](eithers: Either[C, C]*): Seq[C] = eithers.map(_.fold(x => x, x => x))

关于scala - 推断常见的父类(super class)型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42981897/

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