2016-02-19 18 views
9

Có bằng cách nào đó có thể tuyên bố một cái gì đó giống nhưkhai báo một hàm 'type` với `thông số implicit`

type F = (Int, Boolean)(implicit String) => Unit 

trong Scala?

+0

Xin lỗi tôi đã xóa nhận xét của tôi, nó là "bạn có thể làm loại f = (Int, Boolean) => (String) => Unit anyway ". Bạn có quyền nói rằng nó không hoạt động với những lời buộc tội, tôi đoán đó là vì bạn không nên phụ thuộc vào chúng trong các loại của bạn. Một hàm nhận Int và Boolean là một hàm nhận Int và Boolean bất kể hàm implicit trong phạm vi. chỉnh sửa: Ok, các câu trả lời được trả lời bên dưới, một phương pháp không phải là chức năng và các phiên đấu giá không có hàm ý –

Trả lời

18

Có một sự khác biệt rất quan trọng trong Scala giữa "chức năng" và "phương pháp":

Chức năng là những giá trị, và không thể lấy lý lẽ bởi tên tuổi, không thể đa hình, không thể variadic , không thể bị quá tải và không thể có các tham số ngầm định. Trong khi các phương thức có thể có các phương thức này, chúng không thể được truyền đi thành các giá trị.

loại Chức năng chỉ là đặc điểm trong thư viện chuẩn, trong những hình thức sau đây:

trait FunctionN[T1, ..., TN, R] { 
    def apply(x1: T1, ..., xN: TN): R 
} 

Lưu ý cách apply phương pháp trong các loại không không có một danh sách tham số ngầm. Do đó, các hàm sẽ không bao giờ có các tham số ngầm định.

Vì vậy, nếu bạn muốn vượt qua "chức năng" mà phải mất các thông số ngầm, bạn phải tạo đặc điểm riêng của bạn:

trait Function2I1[T1, T2, I1, R] { 
    def apply(a1: T1, a2: T2)(implicit i1: I1): R 
} 

type F = Function2I1[Int, Boolean, String, Unit] 

Bây giờ bạn có thể tạo thể hiện của loại F (mặc dù không phải với cú pháp lambda sáng bóng):

val f = new F { 
    override def apply(x: Int, y: Boolean)(implicit z: String): Unit = ??? 
} 
implicit val x = "hi" 
f(1, true) // implicitly passes x 

Nếu bạn muốn chức năng cà ri không có tham số ngầm, chỉ cần viết (Int, Boolean) => String => Unit.

Nếu bạn muốn chuyển đổi một phương pháp để một chức năng, sử dụng một lambda:

class A { 
    def f(a: String)(implicit b: String): String = a + b 
} 
val a = new A 
val m = a.f(_) // takes the implicit in this scope 
Các vấn đề liên quan