gpt4 book ai didi

scala - 同时保留元素类型 A 和表示类型 Repr 的集合扩展方法

转载 作者:行者123 更新时间:2023-12-02 04:42:58 24 4
gpt4 key购买 nike

作为我的 previous question 的跟进,我可以设计一个隐式类来处理两种类型的SeqLike扩展吗:

import collection.SeqLike
import collection.generic.CanBuildFrom

implicit class Test[A, Repr](val sq: SeqLike[A, Repr]) extends AnyVal {
// no constraints on Repr
def foo[B](f: A => B)(implicit ord: Ordering[B]): Repr = sq.sortBy(f)

// constraint that actually sq is Repr
def bar[B, To](fun: (A, A) => B)(implicit cbf: CanBuildFrom[Repr, B, To]): To = {
val b = cbf(sq) // NO!
// ...
b.result
}
}

bar 方法无法编译,因为我们缺少 typeOf(sq) == Repr 的约束。正如其他人指出的那样,如果我将构造函数更改为 sq: Repr,我们将失去与类型 A 的连接。

现在,Repr 已断开连接。例如:

// in Test:
def isSortedBy[B](fun: A => B)(implicit ord: Ordering[B]): Boolean =
sq.sliding(2, 1).forall {
case a +: b +: _ => ord.lteq(fun(a), fun(b))
case _ => true // happens when it size == 1
}

[error] Test.scala: inferred type arguments [T,Equals] do not conform to method
unapply's type parameter bounds
[T,Coll <: scala.collection.SeqLike[T,Coll]]
[error] case a +: b +: _ => ord.lteq(fun(a), fun(b))
[error] ^

最佳答案

您可以像其他问题一样使用 repr并更改 sq 的类型至 SeqLike而不是 Repr .但与我之前的解决方案不同,您可以将上部类型绑定(bind)到 Repr ( Repr<:SeqLike[A,Repr] ) 来解决剩下的打字问题。例如:

implicit class Test[A, Repr<:SeqLike[A,Repr]](val sq: SeqLike[A, Repr]) extends AnyVal {
// no constraints on Repr
def foo[B](f: A => B)(implicit ord: Ordering[B]): Repr = sq.sortBy(f)

// constraint that actually sq is Repr
def bar[B, To](fun: (A, A) => B)(implicit cbf: CanBuildFrom[Repr, B, To]): To = {
val b = cbf(sq.repr) // NO!
var x = sq.head
sq.tail.foreach { y =>
b+=fun(x,y)
x = y
}
b.result
}
def isSortedBy[B](fun: A => B)(implicit ord: Ordering[B]): Boolean =
sq.sliding(2, 1).forall {
case a +: b +: _ => ord.lteq(fun(a), fun(b))
case _ => true // happens when it size == 1
}
}

关于scala - 同时保留元素类型 A 和表示类型 Repr 的集合扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20427720/

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