Chỉ cần nói mẫu này cho phép bạn thiết lập mối quan hệ giữa hai thông số loại chung.
Chúng ta hãy nhìn vào hình thù LabelledGeneric
kiểu lớp mang đến cho bạn một generic HList
đại diện cho trường hợp lớp:
trait LabelledGeneric[T] {
type Repr
}
T
là loại đầu vào, tức là LabelledGeneric[MyCaseClass]
sẽ cung cấp cho bạn các đại diện HList của MyCaseClass
. Repr
là loại đầu ra, tức là loại HList tương ứng với T
.
Hãy viết một phương thức lấy mẫu Generic
và cần một tham số khác của loại kết xuất. Ví dụ chúng ta có thể sử dụng Keys
để thu thập các tên trường của một nhãn chung
def fieldNames[T](implicit gen: LabelledGeneric[T], keys: Keys[gen.Repr]): keys.Repr …
Trừ rằng điều này không làm việc vì Scala không cho phép bạn truy cập gen
hoặc keys
đây. Chúng ta có thể có một loại cụ thể hoặc một biến kiểu.
Và đó là nơi Aux đi vào chơi: Nó hãy cho chúng tôi "nâng đỡ" gen.Repr
thành một loại biến:
object Generic {
type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 }
}
Như bạn có thể xem các loại Aux
cho chúng ta một cách từ Repr
cho một biến kiểu, vì vậy chúng tôi cuối cùng có thể định nghĩa foo
:
def foo[T, Repr, K](
implicit gen: LabelledGeneric.Aux[T, Repr],
keys: Keys.Aux[Repr, K]
): K …
Nếu bạn đã quen thuộc với Prolog bạn có thể đọc Aux như một vị chứng minh rằng một mối quan hệ giữa hai biến kiểu. Trong ví dụ trên, bạn có thể đọc nó là "LabelledGeneric chứng minh rằng Repr
là đại diện chung với các nhãn của T và Keys.Aux chứng minh rằng K là danh sách tất cả các khóa của Repr".
Xem câu trả lời của tôi [ở đây] (http://stackoverflow.com/a/34548518/334519) để thảo luận. –