Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 保留元素类型A和表示类型Repr的集合扩展方法_Scala_Collections_Implicit Conversion - Fatal编程技术网

Scala 保留元素类型A和表示类型Repr的集合扩展方法

Scala 保留元素类型A和表示类型Repr的集合扩展方法,scala,collections,implicit-conversion,Scala,Collections,Implicit Conversion,作为我的后续工作,我能否设计一个隐式类来处理两种类型的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: Order

作为我的后续工作,我能否设计一个隐式类来处理两种类型的
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]                ^
//测试中:
def-isSortedBy[B](fun:A=>B)(隐式order:Ordering[B]):布尔值=
平方滑动(2,1)。用于所有{
案例a+:b+:=>ord.lteq(fun(a),fun(b))
case=>true//在大小==1时发生
}
[错误]Test.scala:推断的类型参数[T,Equals]不符合方法
取消应用的类型参数边界
[T,Coll ord.lteq(乐趣(a),乐趣(b))
[错误]^

如果我正确理解了问题

  • 如果将类参数
    sq
    设置为
    Repr
    ,则会丢失类型
    a
    (不再有任何推断)

  • 但是如果您将它设置为
    SeqLike[a,Repr]
    ,那么您就失去了它也是
    Repr
    的事实,因此
    cbf(sq)
    不再编译

那么,两者都做怎么样:

implicit class Test[A, Repr](val sq: Repr with SeqLike[A, Repr]) extends AnyVal {
   ...
}
这个版本编译得很好,我可以在一个简单的
列表(1,2,3)
上调用
foo
bar


编辑:如果要将
Repr
类型的值而不是
sq
作为集合进行操作,还需要类型绑定的
Repr,您可以像在其他问题中一样,使用
Repr
并将
sq
的类型更改为
SeqLike
,而不是
Repr
。 但与我以前的解决方案不同,您可以将上限类型绑定到
Repr
Repr B)(隐式cbf:CanBuildFrom[Repr,B,to]):to={
val b=cbf(sq.repr)//否!
var x=平方水头
sq.tail.foreach{y=>
b+=乐趣(x,y)
x=y
}
b、 结果
}
def-isSortedBy[B](fun:A=>B)(隐式order:Ordering[B]):布尔值=
平方滑动(2,1)。用于所有{
案例a+:b+:=>ord.lteq(fun(a),fun(b))
case=>true//在大小==1时发生
}
}

我认为
self.slideing
应该是
sq.slideing
对吗?@stew-是的,很抱歉这是复制+粘贴的错误
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
    }
}