私はここでほとんど私が知りたかったかを説明ラースHupel(そう、すべてのクレジットは彼に適用されます)、からの回答を貼り付けます。私はそれをここで刺しを与えるつもりだ
を。私は型のメンバーについて話すとき、この機能の使用が をクリアすると思います。
trait Function {
type Out[In]
def apply[In](x: In): Out[In]
}
は、この戻り値の型が 入力タイプによって異なります(一般的な)関数のようになります。
では、次の特性を実装する必要があるとします。例の1つの例:
val someify = new Function {
type Out[In] = Option[In] def
apply[In](x: In) = Some(x)
}
someify(3) res0: Some[Int] = Some(3)
これまでのところ、とても良いです。今、あなたは定数関数をどのように定義しますか?
val const0 = new Function {
type Out[In] = Int
def apply[In](x: In) = 0
}
const0(3) res1: const0.Out[Int] = 0
(タイプconst0.Out[Int]
がInt
と同等であるが、それはそのように印刷さ ない。)typeパラメータIn
が実際に使用されていない方法
注意。だから、ここであなたが_
でそれを書くことができる方法 です:
val const0 = new Function {
type Out[_] = Int
def apply[In](x: In) = 0
}
その場合の_
のだと思い が実際に参照することができないタイプのパラメータの名前として。これは、パラメータを気にしないタイプ レベルで機能するためにちょうど値のような レベル:
(_: Int) => 3 res4: Int => Int = <function1>
除いて...
type Foo[_, _] = Int
<console>:7: error: _ is already defined as type _
type Foo[_, _] = Int
がでていることを比較:
(_: Int, _: String) => 3 res6: (Int, String) => Int = <function2>
結論として:
type F[_] = ConstType // when you have to implement a type member def
foo[_](...) // when you have to implement a generic method but don't
// actually refer to the type parameter (occurs very rarely)
あなたが言及した主なことは、class A[_]
は、完全に対称である ですが、実際の使用例はありません。
この考えてみましょう:
trait FlyingDog[F[_]] { def swoosh[A, B](f: A => B, a: F[A]): F[B] }
は今、あなたはあなたの平野 古いclass A
ためFlyingDog
のインスタンスを作成するとします。
代わりclass A[_]
を宣言します。
は、二つの解決策があります。 (。それをしないでください)
型ラムダ使用する:あなたがここで意味することはないが実存タイプです
new FlyingDog[({ type λ[α] = A })#λ]
あるいは
new FlyingDog[({ type λ[_] = A })#λ]
を私が言ったことの意味。 – sschaef