2013-06-28 23 views
5

Như hầu hết các bạn có thể biết bạn có thể xác định chức năng trong 2 cách thức scala, có những 'def' phương pháp và phương pháp lambda ...Làm cách nào để tạo các hàm lambda chung trong Scala?

làm cho 'def' loại generic là khá thẳng về phía trước

def someFunc[T](a: T) { // insert body here 

những gì tôi đang gặp rắc rối với ở đây là làm thế nào để thực hiện những điều sau generic:

val someFunc = (a: Int) => // insert body here 

dĩ nhiên ngay bây giờ a là một số nguyên, nhưng những gì tôi cần phải làm gì để làm cho nó chung chung?

val someFunc[T] = (a: T) => không hoạt động, cũng như thế val someFunc = [T](a: T) =>

Là nó thậm chí có thể làm cho họ chung chung, hoặc nên tôi chỉ dính vào 'def' biến thể?

+4

Có một số cách để xác định các hàm trong Scala, nhưng sử dụng 'def' không phải là một trong số chúng! Từ khóa 'def' được sử dụng để định nghĩa các phương thức *, có nghĩa là một tạo phẩm của JVM. Với thông tin kiểu phù hợp, Scala có thể tự động nâng một phương thức lên một hàm tương ứng, làm cho nó trở nên trong suốt và hoàn toàn không có ma sát, nhưng dù sao thì hai thứ này lại khác nhau.Xem http://stackoverflow.com/questions/17203510/partially-applied-functions-with-all-arguments-missing-in-scala/17203833#17203833 –

+1

google điều gì đó liên quan đến chức năng và scala và tôi đảm bảo với bạn rằng hầu hết các kết quả sẽ hiển thị các phương pháp và mọi người đề cập đến các phương thức như hàm, do đó sự nhầm lẫn –

+0

Như dễ hiểu hoặc có thể giải thích được vì sự nhầm lẫn, nó không phục vụ người học viên làm mờ sự khác biệt. –

Trả lời

7

Như Randall Schulz cho biết, def không tạo ra một chức năng, nhưng một phương pháp. Tuy nhiên, nó có thể trả về một hàm và theo cách này bạn có thể tạo các hàm chung như hàm identity trong Predef. Điều này sẽ trông như thế này:

def myId[A] = (a: A) => a 

List(1,2,3) map myId 
// List(1,2,3) 

List("foo") map myId 
// List("foo") 

Nhưng lưu ý, đó gọi myId mà không cần bất kỳ loại thông tin suy luận Nothing. Trong trường hợp trên nó hoạt động, vì những suy luận kiểu sử dụng chữ ký của map, đó là map[B](f: A => B), nơi A là loại danh sách và B được infered để giống như A, bởi vì đó là chữ ký của myId.

+0

Tôi thực sự đã viết nó như là một giải pháp trước đây, nhưng tôi đã nhận xét về nó rồi trở thành chức năng trả về chức năng, và do đó không phải những gì tôi đang tìm kiếm, tôi đã xóa nó ... Nhưng có vẻ như tôi không phải là người duy nhất đã đưa ra một phương pháp (một cái gì đó rất nhiều người gọi chức năng trong scala) mà sau đó trả về một chức năng –

+0

Nếu phương pháp có tác dụng phụ miễn phí, họ về cơ bản là tương đương với chức năng. Trong các ngôn ngữ khác như haskell, mọi hàm với tham số cũng trả về các hàm, vì mọi hàm trong haskell đều được curried. Trên thực tế, phương thức myId cũng là một hàm curried và giống như khi bạn tạo toàn bộ một thứ như một phương thức và sau đó áp dụng một phần nó với 0 tham số đã cho. – drexin

+0

Tôi rất ý thức về khái niệm về cà ri; câu hỏi này xuất phát từ tôi cố gắng tạo ra một hàm với chữ ký kiểu này: '(a -> b) -> (a, c) -> (b, c)' nhưng vì mục đích đơn giản, tôi giữ nó thành một chữ cái duy nhất loại chung hơn là ba. Chữ ký kiểu mà tôi đã trình bày, như bạn đã biết, một hàm nhận 2 tham số và trả về một tuple, và tùy thuộc vào số lượng tham số được sử dụng, hàm trả về bộ hoặc hàm nhận một bộ và trả về một bộ tuple. .. Vì vậy, có tôi là quen thuộc với ý tưởng :) –

3

Tôi không tin là có thể. Bạn có thể nhìn vào bài trước này để biết thêm chi tiết:

How can I define an anonymous generic Scala function?

Cách duy nhất xung quanh nó (là một trong những câu trả lời đề cập đến) là mở rộng cái gì đó như FunctionX và sử dụng một generic ở cấp lớp và sau đó sử dụng trong quá trình ghi đè hàm apply.

2

Tôi không tin điều đó có thể, nhưng tôi là người bi quan.

http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/

Edit:

Nói cho tôi biết nếu điều này không phải là những gì bạn đang hỏi, nhưng điều này là lý do tại sao câu trả lời chấp nhận không phải là những gì tôi nghĩ bạn đã yêu cầu, vui lòng xem link:

scala> :pa 
// Entering paste mode (ctrl-D to finish) 

def myId[A] = (a: A) => a 

List(1,2,3) map myId 
// List(1,2,3) 

List("foo") map myId 
// List("foo") 

// Exiting paste mode, now interpreting. 

myId: [A]=> A => A 
res0: List[String] = List(foo) 

scala> val f1 = myId[Int] 
f1: Int => Int = <function1> 

scala> val f2 = myId[String] 
f2: String => String = <function1> 

scala> List(1,2,3) map f2 
<console>:10: error: type mismatch; 
found : String => String 
required: Int => ? 
       List(1,2,3) map f2 
          ^

scala> List("foo") map f1 
<console>:10: error: type mismatch; 
found : Int => Int 
required: String => ? 
       List("foo") map f1 
          ^

Giá trị hàm không đa hình, tức là chung chung.