2016-05-27 12 views
7

Cho một typeclass Printer với một loại phụ thuộc Show[A]:Làm cách nào để mã hóa phương thức này với nhóm tham số ngầm có chứa loại phụ thuộc?

trait Printer { 
    type Show[A] 
    def show[A](x: A)(implicit z: Show[A]): String 
} 

object Printer { 
    // the intent here is this is the dumb fallback 
    // and a user can have a better alternative in scope 
    implicit val dumbPrinter: Printer = new Printer { 
    type Show[A] = DummyImplicit 
    def show[A](x: A)(implicit z: DummyImplicit): String = x.toString 
    } 
} 

Làm thế nào để mã hóa phương pháp này:

def r[A](x: A)(implicit printer: Printer, show: printer.Show[A]): String = 
    printer.show(x)(show) 

Tôi đã cố gắng để thích ứng với mã làm việc trong @ MilesSabin của ý chính https://gist.github.com/milessabin/cadd73b7756fe4097ca0 và @ Bài đăng trên blog của TravisBrown https://meta.plasm.us/posts/2015/07/11/roll-your-own-scala/, nhưng tôi không thể tìm thấy mã hóa hoạt động.

+0

Không phải là nó là một vấn đề của việc thiếu nhiều thông số phần ngầm tại Scala? Tôi nghĩ rằng Miles Sabin đã thực hiện một SI với điều này gần đây, nhưng tôi không thể tìm thấy nó. (chỉnh sửa: Tôi thấy điều này đã được đề cập trong gist bạn tham khảo) – Haspemulator

+0

@Haspemulator Đúng. –

+0

Tôi không xem xét các ví dụ. Nhưng làm thế nào về việc tạo ra một kiểu mới để xử lý một trường hợp 'Máy in' và' Hiển thị [A] ':' trường hợp có thể in [A] (máy in: Máy in) (ẩn hiển thị: printer.Show [A]) '. Sau đó, làm cho 'r' yêu cầu một' Có thể in [A] '. – ziggystar

Trả lời

0

Bạn có thể buộc kiểu suy luận một bước tại một thời điểm bằng cách giới thiệu bối cảnh trung gian:

object example { 

    trait AnyPrinter { 
    type Show <: AnyShow 
    } 

    trait AnyShow { 
    type X 
    def apply(x: X): String 
    } 

    def print[P <: AnyPrinter](implicit p: P): print[P] = new print[P] 

    class print[P <: AnyPrinter] { 
    def it[E](e: E)(implicit s: P#Show { type X = E }): String = s(e) 
    } 

    // the intent here is this is the dumb fallback 
    // and a user can have a better alternative in scope 
    implicit object DumbPrinter extends AnyPrinter { 
    type Show = AnyDumbShow 
    } 
    trait AnyDumbShow extends AnyShow { 
    def apply(x: X): String = x.toString 
    } 
    case class DumbShow[Z]() extends AnyDumbShow { type X = Z } 
    implicit def dumbShow[Z]:DumbShow[Z] = DumbShow() 

    val buh: String = print.it(2) 
} 
Các vấn đề liên quan