最近、存在型と型エイリアス ( https://softwaremill.com/scala-riddle )を含む興味深い scala なぞなぞがあり、型エイリアスが機能しない場合は、制限付きの抽象型メンバーを試す必要があることがわかりました。
特定の状況でどの種類のメンバーを適用する必要があるかを教えてくれるパターンがわかりません。ドキュメントで答えが見つかりません。実装の詳細でしょうか?
そのようなパターンを見つけるのを手伝ってくれる人、または少なくともいくつかの新しい手がかりを教えてくれる人がいることを願っています..
コードを機能させる方法
内部では、PairT
型エイリアス ( type T1 = A
) を厳密に境界付けられた抽象型 ( type T1 >: A <: A
) に置き換えました。.. 動作します (scalac 2.11.4)。
さらに興味深いのPairC
は、具体的なクラスである は、型エイリアスでのみ機能します。それらを制限付き抽象型メンバーに置き換えようとすると、コンパイル エラーが発生します。
以下は、私の変更後のコード全体です。
package so1
import scala.language.existentials
object SOPuzzle {
type PairT[F, S] = {
type T1 >: F <: F
type T2 >: S <: S
}
class PairC[F, S] {
type T1 = F
type T2 = S
}
case class TMap[T, U](a: T, b: U) {
def consumeA(a: T): T = a
def consumeB(b: U): U = b
}
type MapC2[A] = TMap[p.T1, p.T2] forSome {val p: PairC[A, A]}
type MapC2V2[A] = TMap[PairC[A, A]#T1, PairC[A,A]#T2]
type MapT2[A] = TMap[p.T1, p.T2] forSome {val p: PairT[A, A]}
type MapT2V2[A] = TMap[PairT[A, A]#T1, PairT[A, A]#T2]
val c2: MapC2[Int] = TMap(1, 2)
val c2v2: MapC2V2[Int] = TMap(1, 2)
val t2: MapT2[Int] = TMap(1, 2)
val t2v2: MapT2V2[Int] = TMap(1, 2)
val i1:Int = c2.consumeA(0)
val i2:Int = c2.consumeB(0)
val i3:Int = c2v2.consumeA(0)
val i4:Int = c2v2.consumeB(0)
val i5:Int = t2.consumeA(0)
val i6:Int = t2.consumeB(0)
val i7:Int = t2v2.consumeA(0)
val i8:Int = t2v2.consumeB(0)
}