Tôi chỉ chạy vào một chênh lệch kỳ lạ giữa chức năng và các đối tượng (scala 2.10):Chuyển đổi ngầm định cho defs/lambdas trong Scala?
implicit def conv(c: Int => String) : (PrintStream => Int => Unit) = p => v => p.println(c(v))
def f(h: PrintStream => Int => Unit) : Unit = h(System.out)(1)
def a(x: Int) = x.toString
val b = (x: Int) => x.toString
// def main(args: Array[String]) = f(a) // fail
// def main(args: Array[String]) = f((x: Int) => x.toString) // fail
def main(args: Array[String]) = f(b) // ok
Tại sao lại có một sự khác biệt giữa defs/literals lambda và Vals lambda?
Cập nhật: rõ ràng, các vấn đề không xảy ra cho các chức năng nhị phân: Implicit conversion of a function to a second-order-function only works if the function to convert has at least two parameters
Tôi đã kiểm tra này, và thực sự đoạn mã sau hoạt động:
implicit def conv(c: (Int,Unit) => String) : (PrintStream => Int => Unit) = p => v => p.println(c(v,()))
def f(h: PrintStream => Int => Unit) : Unit = h(System.out)(1)
def a(x: Int, y : Unit) = x.toString
val b = (x: Int, y : Unit) => x.toString
def main(args: Array[String]) = f(a) // ok
def main(args: Array[String]) = f((x: Int, y: Unit) => x.toString) // ok
def main(args: Array[String]) = f(b) // ok
Tương tự như vậy, chức năng Nullary không đặt ra một vấn đề , hoặc:
implicit def conv(c:() => String) : (PrintStream => Int => Unit) = p => v => p.println(c())
def f(h: PrintStream => Int => Unit) : Unit = h(System.out)(1)
def a() = "1"
val b =() => "1"
def main(args: Array[String]) = f(a) // ok
def main(args: Array[String]) = f(() => "1") // ok
def main(args: Array[String]) = f(b) // ok
Vì vậy, hãy nói lại câu hỏi: tại sao điều này không hoạt động cho các phương pháp và chức năng UNARY?
Cập nhật: vấn đề cũng dường như có liên quan đến loại mục tiêu (loại đối số f). Sau đây cũng làm việc (thời gian này, ủng hộ việc "đếm eta-mở rộng như hop", bởi vì chúng ta cần phải tạo ra một giá trị phương pháp từ một sử dụng _)
implicit def conv(c: Int => String) : Unit =()
def f(h: Unit) : Unit = System.out.print("?")
def a(x: Int) = x.toString
val b = (x: Int) => x.toString
def main(args: Array[String]) = f(a _) // ok
def main(args: Array[String]) = f((x: Int) => x.toString) // ok
def main(args: Array[String]) = f(b) // ok
m aybe scalac xem xét chuyển đổi của defs/lambda literals thành FunctionN đã là một hop ngầm (trong đó nhiều nhất là một được phép)? –
Chỉ cần kiểm tra thông số kỹ thuật. Eta-mở rộng nên đến miễn phí, vì vậy ba nên tương đương với w.r.t. xem ứng dụng: "Chúng tôi nói, loại T tương thích với loại U nếu T yếu phù hợp với U sau khi áp dụng các ứng dụng xem và mở rộng eta *." –
http://stackoverflow.com/questions/28456012/implicit-conversion-of-a-function-to-a-second-order-function-only-works-if-the-f –