[SCALA] 일반적인 방법에서 원래 수집 유형을 반환
SCALA일반적인 방법에서 원래 수집 유형을 반환
우리가 수집 동일 미니멀리즘의 모든 요소를 반환 minBy 같은 기능을하고 싶은 말 :
def multiMinBy[A, B: Ordering](xs: Traversable[A])(f: A => B) = {
val minVal = f(xs minBy f)
xs filter (f(_) == minVal)
}
scala> multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last)
res33: Traversable[java.lang.String] = List(zza, zzza)
지금까지 좋은, 그래서 우리는에 이동 다시 대신 우리의 초기 목록을 가지고 것을 제외하고.
난에 서명을 변경 시도 그래서
def multiMinBy[A, B: Ordering, C <: Traversable[A]](xs: C)(f: A => B)
희망 나는에 이동 [A]가 아니라 다시 C를 얻을 수 있습니다. 그러나, 나는 아무것도 다시 얻지 않는다 :
scala> multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last)
<console>:9: error: inferred type arguments [Nothing,Nothing,List[java.lang.String]]
do not conform to method multiMinBy's type parameter bounds [A,B,C <: Traversable[A]]
나는 A가 추정되기 전에 우리는 C가 인수에 나타나는 때문에이 생각? 나는 인수의 순서를 뒤집어 및 캐스트를 추가 그래서 :
def multiMinBy[A, B: Ordering, C <: Traversable[A]](f: A => B)(xs: C) = {
val minVal = f(xs minBy f)
(xs filter (f(_) == minVal)).asInstanceOf[C]
}
우리는 다음과 같이 호출 할 필요가 제외되는 작동 :
multiMinBy((x: String) => x.last)(List("zza","zzza","zzb","zzzb"))
올바른 수집 유형 등을 가져 오는 동안, 원래의 구문을 유지하는 방법이 있나요?
해결법
-
==============================
1.나는 마일 사빈 솔루션은 너무 복잡하다 생각합니다. 스칼라의 수집은 이미 아주 작은 변화와 함께 작동하도록하는 데 필요한 기계를 가지고 :
나는 마일 사빈 솔루션은 너무 복잡하다 생각합니다. 스칼라의 수집은 이미 아주 작은 변화와 함께 작동하도록하는 데 필요한 기계를 가지고 :
import scala.collection.TraversableLike def multiMinBy[A, B: Ordering, C <: Traversable[A]] (xs: C with TraversableLike[A, C]) (f: A => B): C = { val minVal = f(xs minBy f) xs filter (f(_) == minVal) }
-
==============================
2.어떻게 CanBuildFrom 사용에 대한?
어떻게 CanBuildFrom 사용에 대한?
import scala.collection.immutable._ import scala.collection.generic._ def multiMinBy[A, B, From[X] <: Traversable[X], To](xs: From[A])(f: A => B) (implicit ord: Ordering[B], bf: CanBuildFrom[From[_], A, To]) = { val minVal = f(xs minBy f) val b = bf() b ++= (xs filter (f(_) == minVal)) b.result } scala> multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last) res1: List[java.lang.String] = List(zza, zzza)
-
==============================
3.귀하의 문제는 GenTraversable [A]에하는 방법으로 볼 때 필터 메소드의 결과 유형이 GenTraversable [A]보다 더 정확한 없다 (나는이 대답에 이동 [A] 대신 사용할 것이다하는) 것입니다. 불행하게도 multiMinBy 방법의 신체 내에서 그건 당신이 XS에 대해 알고 전부 기록한다.
귀하의 문제는 GenTraversable [A]에하는 방법으로 볼 때 필터 메소드의 결과 유형이 GenTraversable [A]보다 더 정확한 없다 (나는이 대답에 이동 [A] 대신 사용할 것이다하는) 것입니다. 불행하게도 multiMinBy 방법의 신체 내에서 그건 당신이 XS에 대해 알고 전부 기록한다.
당신이 multiMinBy의 서명이 더 정확한 수 있도록해야합니다 후있어 결과를 얻으려면. 여전히 상대적으로 개방 컨테이너 유형을 떠나는 동안이 일을 한 가지 방법은 다음과 같은 구조 유형을 사용하는 것입니다,
type HomFilter[CC[X] <: GenTraversable[X], A] = CC[A] { def filter(p : A => Boolean) : CC[A] } def multiMinBy[CC[X] <: GenTraversable[X], A, B: Ordering] (xs: HomFilter[CC, A])(f: A => B) : CC[A] = { val minVal = f(xs minBy f) xs filter (f(_) == minVal) }
구조적 타입 HomFilter은 우리가 multiMinBy의 인수가 원하는 결과 유형 필터 방법이 있어야합니다 주장 할 수 있습니다.
샘플 REPL 세션,
scala> val mmb = multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last) mmb: List[String] = List(zza, zzza)
마음에 곰이 컨테이너 단지에 이동하는 것이보다 엄격한 요구 사항입니다 : GenTraversable의 아형이 방법으로 정기적으로하지 필터 방법을 정의하는 것이 허용합니다. 정적에서 같은 유형의 값을 방지 할 수 위의 서명 후 당신 행동이 있다는 아마도 ... multiMinBy에 전달된다.
from https://stackoverflow.com/questions/8235462/returning-original-collection-type-in-generic-method by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 어떻게 스칼라 I 패턴 일치 배열은 무엇입니까? (0) | 2019.11.12 |
---|---|
[SCALA] 볼품를 사용하여 중첩 된지도에 중첩 된 경우 클래스를 변환 (0) | 2019.11.12 |
[SCALA] 어떻게 하나 개의 큰 PNG 파일에 여러 개의 PNG 파일을 결합? (0) | 2019.11.12 |
[SCALA] MutableList와 ListBuffer의 차이 (0) | 2019.11.12 |
[SCALA] 어떻게 스칼라 스트림 클래스와 큰 CSV 파일을 읽습니까? (0) | 2019.11.12 |