ああ、これは古いものです!私は、コードをクリーンアップすることにより、ビットを開始し、現在の慣用的な慣習とラインにそれを引っ張っます:
case class Flat[T, U](fn: T => List[U])
implicit def recFlattenFn[T, U](
implicit f: Flat[T, U] = Flat((xs: T) => List(xs))
) = Flat((xs: List[T]) => xs flatMap f.fn)
def recFlatten[T, U](xs: List[T3])(implicit f: Flat[List[T], U]) = f fn xs
その後、前置きなしに、コードを打破します。まず、我々はFlat
クラスがあります。
case class Flat[T, U](fn: T => List[U])
をこれは、関数T => List[U]
ためという名前のラッパー、タイプT
のインスタンスが与えられたときList[U]
を構築する機能以外の何ものでもありません。ここでT
は、List[U]
、またはU
、またはList[List[List[U]]]
などであってもよいことに注意してください。通常、このような関数はパラメータのタイプとして直接指定できます。しかし、私たちは暗黙のうちにこれを使用するつもりです。そのため、名前付きラッパーは暗黙の競合のリスクを回避します。
その後、recFlatten
から逆方向に働く:
def recFlatten[T, U](xs: List[T])(implicit f: Flat[List[T], U]) = f fn xs
この方法は、(List[T]
を)xs
を取り、U
に変換します。これを実現するために、それはFlat[T,U]
の暗黙のインスタンスを検索し、囲まれた関数を呼び出し、fn
はその後、本当の魔法:
implicit def recFlattenFn[T, U](
implicit f: Flat[T, U] = Flat((xs: T) => List(xs))
) = Flat((xs: List[T]) => xs flatMap f.fn)
これは、recFlatten
で必要とされる暗黙のパラメータを満たし、それはまた別の暗黙ののparamaterを取ります。最も決定的:Flat[T,U]
場合T
がList
あるよう
recFlattenFn
は、独自の暗黙のパラメータとして機能することができ、それがフラット返し
- [一覧[X]は、X]、そう
recFlattenFn
は、暗黙的に解決されます
- 暗黙的な解決が失敗した場合、暗黙的な
f
はデフォルト値にフォールバックすることができます(つまりT
がList
ではありません)
Perha PSこれは最高の例の一つの文脈で理解されています
recFlatten(List(List(1, 2, 3), List(4, 5)))
List[List[Int]]
- 暗黙のルックアップが `フラット[一覧[一覧[INT]]のために試みられているようなタイプ
T
が、推測されU]
- これは再帰的に
recFlattenFn
は概して定義にマッチさ:
が
List
ではないので
[Int,_]
は、この試合を失敗のparams
recFlattenFn
だけ
Flat[List[X], X]
の暗黙的な検索やタイプと一致することをは
recFlattenFn[List[List[Int]], U] (f =
recFlattenFn[List[Int], U] (f =
Flat[Int,U]((xs: T) => List(xs)) //default value
)
)
注意。これがデフォルト値へのフォールバックをトリガするものです。
タイプ推論はまた、再帰の各レベルでU
PARAMを解決する、その構造まで逆方向に動作:
Flat
インスタンスだけネスティング、
flatMap
を行う(最内を除く)各一つ
recFlattenFn[List[List[Int]], Int] (f =
recFlattenFn[List[Int], Int] (f =
Flat[Int,Int]((xs: T) => List(xs)) //default value
)
)
入れ子になったList
構造の1つのレベルを展開する操作。最も内側のFlat
は、すべての個々の要素を1つのList
にバックアップします。
Q.E.D.
ありがとうございました。私はあなたの例では、型パラメータはラッピングによって外されていると思います。これは、 'recFlatten [List [Int]、Int](list(1,2,3)、List(4,5)))をコンパイルします(recFlattenFn [List [Int]、Int](f = recFlattenFn [Int 、INT](F = フラット[INT、INT]((XS:INT)=>一覧(XS))//デフォルト値 ) ) ) ' – huynhjl
ピタッは、今更新:) –