質問

「追加」メソッド(たとえば、Javaコレクション)を持つコレクションを定義する構造タイプを定義しようとしています。これを使用して、特定のコレクションで動作するいくつかの高次関数を定義したい

object GenericTypes {
  type GenericCollection[T] = { def add(value: T): java.lang.Boolean}
}

import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection[X]] {
    def map[V](fn: (T) => V): CollectionType[V]
    ....
}

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]

これは、次のエラーではコンパイルされません

error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement 

汎用コレクションでパラメーターを削除して、メソッドに掲載しようとしました。

object GenericTypes {
  type GenericCollection = { def add[T](value: T): java.lang.Boolean}
}
import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection]

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]

しかし、私は別のエラーを取得します:

error: type arguments [T,java.util.List] do not conform to trait HigherOrderFunctions's type parameter bounds [T,CollectionType[X] <: org.scala_tools.javautils.j2s.GenericTypes.GenericCollection]

SCALAで抽象的な型付けパラメーターで構造タイピングを使用する方法について、誰かが私にアドバイスをすることができますか?または、私が達成しようとしていることを達成する方法は?本当にありがとう!

役に立ちましたか?

解決

あなたが見ることができるように チケット1906 実行時にタイプの情報が欠落しているため、構造タイプの外側で定義された抽象型を使用することはできません。

これはに記載されています SCALA言語参照(3.2.7化合物タイプ):

Within a method declaration in a structural refinement, the type of
any value parameter may only refer to type parameters or abstract types that are
contained inside the refinement.

タイプに新しいメソッドを追加する通常の方法は、暗黙的なタイプ変換です。

trait HigherOrderFunctions[T, CC[_]] {
    def zap[V](fn: () => V): CC[V]
}

class RichJList[T](list: java.util.List[T]) extends HigherOrderFunctions[T, java.util.List]{
    def zap[V](fn: () => V): java.util.List[V] = {
        val l = new java.util.ArrayList[V]
        l add fn()
        l
    }
}
implicit def list2RichList[T](l : java.util.List[T]) = new RichJList(l)
new java.util.ArrayList[AnyRef]() zap (() => 2)

コンパイラがタイプがZAPメソッドを逃したことを確認した場合、範囲で暗黙の変換方法(ここではlist2richList)を備えたzapメソッドを持つタイプに変換します。

scala> new java.util.ArrayList[AnyRef]() zap (() => 2)
res0: java.util.List[Int] = [2]
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top