2010-03-01 29 views
11

Tôi đã thấy việc sử dụng ví dụ Function.tupled này trong một ví dụ khác answer: Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length).Chức năng và cú pháp giữ chỗ

Nó hoạt động:

scala> Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length) 
<console>:5: warning: method tupled in object Function is deprecated: 
Use `f.tuple` instead 
     Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length) 
               ^
res0: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

Dường như tôi có thể làm mà không nếu tôi không muốn sử dụng cú pháp giữ chỗ.

scala> Map(1 -> "one", 2 -> "two") map (x => x._1 -> x._2.length) 
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

Việc sử dụng trực tiếp của cú pháp giữ chỗ không hoạt động:

scala> Map(1 -> "one", 2 -> "two") map (_._1 -> _._2.length) 
<console>:5: error: wrong number of parameters; expected = 1 
     Map(1 -> "one", 2 -> "two") map (_._1 -> _._2.length) 

làm việc như thế nào Function.tupled? Dường như có rất nhiều điều xảy ra trong Function.tupled(_ -> _.length). Tôi cũng sử dụng nó như thế nào để không nhận được cảnh báo không dùng nữa?

+0

@huynhjl Việc ngừng sử dụng Function.tupled là kết quả của sự hiểu biết rằng một hàm phải biết cách tự giải mã mà không cần trợ giúp. Tuy nhiên, điều đó thực sự không hoạt động tốt với suy luận kiểu. Tôi chắc chắn hy vọng họ không loại bỏ Function.tupled mà không làm cho các loại inferencer đủ thông minh để có được xung quanh vấn đề này. –

+0

Tôi không được chấp nhận nó ngay bây giờ. – extempore

Trả lời

15

CẬP NHẬT Khoản khấu hao là removed hôm nay, để giải quyết vấn đề này.


Tupling một chức năng chỉ đơn giản là thích ứng FunctionN[A1, A2, ..., AN, R] đến một Function1[(A1, A2, ..., AN), R]

Function.tuple được phản đối ủng hộ FunctionN#tupled. A (có thể là ngoài ý muốn) Hậu quả của việc này là loại inferencer không thể suy ra các loại tham số trong:

scala> Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled     
<console>:5: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$minus$greater(x$2.length)) 
     Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled 
             ^
<console>:5: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$minus$greater(x$2.length)) 
     Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled 

Bất kỳ trong số này sẽ làm việc:

scala> Map(1 -> "one", 2 -> "two") map { case (a, b) => a -> b.length } 
res8: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

scala> Map(1 -> "one", 2 -> "two") map ((_: Int) -> (_: String).length).tupled   
res9: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

scala> Map(1 -> "one", 2 -> "two") map ((p: (Int, String)) => p._1 -> p._2.length) 
res12: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

tôi đề nghị bạn đọc câu trả lời cho này câu hỏi gần đây để có được một sự hiểu biết sâu sắc hơn về '_' trong literals chức năng, và loại suy luận làm việc như thế nào:

In Scala, what is the difference between using the `_` and using a named identifier?

CẬP NHẬT

Để trả lời nhận xét, nó có.

scala> val f = (x:Int, y:String) => x + ": " + y 
f: (Int, String) => java.lang.String = <function2> 

scala> f.tupled 
res0: ((Int, String)) => java.lang.String = <function1> 

scala> Map(1 -> "1") map f.tupled 
res1: scala.collection.immutable.Iterable[java.lang.String] = List(1: 1) 

Điều này yêu cầu Scala 2.8. Lưu ý rằng bản đồ Map # có thể dẫn đến một bản đồ khác, nếu kiểu trả về của hàm là Tuple2, nếu không một Danh sách, như trên.

+0

Cảm ơn bạn đã trả lời. Điều làm tôi bối rối là điều này không có tác dụng: 'val f = (x: Int, y: String) => x +": "+ y; f.tupled'. Không nên trả về một phiên bản của f mà hoạt động trên một (Int, String) tuple? – huynhjl

+0

ok, tôi hiểu, điều đó giải thích rất nhiều. Tôi đã thử lại với 2.8.0.Beta1 và nó hoạt động như mong đợi. Tôi đã thử trước đó với 2.8.0.Beta1-RC5 mà tôi đã có trong con đường của tôi. Tôi cần loại bỏ RC5 ... – huynhjl

Các vấn đề liên quan