2012-06-10 29 views
10

Tôi có một số câu hỏi liên quan đến chức năng thu được. Ở đây tôi hỏi từng người mộtcác câu hỏi liên quan đến chức năng đã được xử lý trong Scala

1) http://twitter.github.com/scala_school/basics.html đưa ra ví dụ về chức năng đã kết thúc - Tôi nghĩ đó là định nghĩa hàm, nhưng thực tế là không. REPL không nhận ra đây là một tuyên bố hợp lệ.

multiplyThenFilter { m: Int => m * 2 } { n: Int => n < 5} 

2) Tại sao chúng ta không thể xác định hàm từ phương pháp được tham số hóa một phần? tức là, có gì sai với định nghĩa sau đây?

scala> def multiply(m: Int, n: Int): Int = m * n 
multiply: (m: Int, n: Int)Int 

scala> val timesTwo = multiply(2,_) 
<console>:11: error: missing parameter type for expanded function ((x$1) => multiply(2, x$1)) 
     val timesTwo = multiply(2,_) 
           ^

3) Tại sao chúng ta không thể thực hiện chức năng được tham số hóa một phần? tức là, có gì sai với định nghĩa sau đây?

scala> (multiply(_,_)).curried 
    res13: Int => (Int => Int) = <function1> // THIS IS OK 

scala> (multiply(20,_)).curried 
<console>:12: error: missing parameter type for expanded function ((x$1) => multiply(20, x$1)) 
       (multiply(20,_)).curried 
         ^
+0

1) Nó không hợp lệ, vì nó phải được khai báo trước. Ví dụ, như thế: 'def multiplyThenFilter (a: Int => Int) (b: Int => Boolean) = {Danh sách (1,2,3,4) .map (a).filter (b)} ' –

+0

1) MultiplyThenFilter biến mất ngay bây giờ. Bạn không phải là người duy nhất bị nhầm lẫn bởi nó :-) –

Trả lời

11

Câu hỏi 1

Các Scala Trường ví dụ khó hiểu-nó chắc chắn không phải là một định nghĩa. Có an issue mở cho nó trên GitHub, vì vậy có lẽ đó là một lỗi. Bạn có thể tưởng tượng một định nghĩa hợp lý có thể trông như thế này:

def multiplyThenFilter(f: Int => Int)(p: Int => Boolean): Int => Option[Int] = { 
    i => 
    val j = f(i) 
    if (p(j)) Some(j) else None 
} 

(Hoặc tương đương, f andThen (Some(_) filter p).)

Sau đó, ví dụ sẽ là một chức năng mà tăng gấp đôi đầu vào của nó và trả về kết quả trong một Some nếu nó ít hơn 5 và None nếu không. Nhưng không ai biết chính xác tác giả dự định cho đến khi có phản hồi cho vấn đề đó.


Câu hỏi 2

Lý do mà timesTwo của bạn không hoạt động chỉ là trình biên dịch Scala không hỗ trợ loại suy luận kiểu-thấy this questionmy answer there cho một chút chi tiết có liên quan. Bạn sẽ cần phải thực hiện một trong những điều sau:

def multiply(m: Int, n: Int): Int = m * n  
val timesTwo = multiply(2, _: Int) 

def multiply(m: Int)(n: Int): Int = m * n  
val timesTwo = multiply(2) _ 

I.e., nếu bạn muốn suy luận, bạn cần sử dụng nhiều danh sách tham số. Nếu không, bạn phải giúp trình biên dịch ra với loại.


Câu hỏi 3

Đối với câu hỏi thứ ba của bạn, giả sử chúng ta đã có những điều sau đây để tránh vấn đề trong câu hỏi của bạn thứ hai:

val timesTwo = multiply(2, _: Int) 

Đây là một Function1, mà chỉ doesn' t có phương thức curried — bạn cần Function2 (hoặc Function3, v.v.) cho điều đó.

Điều đó không có ý nghĩa khi nói về việc cắt một hàm với một đối số duy nhất. Currying có một hàm với nhiều đối số và cung cấp cho bạn một hàm lấy một đối số duy nhất trả về một hàm khác (mà chính nó có thể lấy một đối số duy nhất và trả về một hàm khác, v.v.).

+0

là hai hàm 'timesTwo' được xác định trong "lần valTwo = nhân (2, _: Int)" và "val timesTwo = multiplly (2) _" trong câu trả lời của bạn Câu hỏi 2 cùng loại? – chen

+0

Có, chúng đều là 'Int => Int' (hoặc tương đương' Hàm1 [Int, Int] '). –

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