2010-03-25 38 views
9

Tôi mới sử dụng Scala (Phiên bản runner mã Scala 2.7.7.final), và tôi thực sự không hiểu tại sao nó yêu cầu người gọi để cung cấp kiểu tham số khi chúng ta đang sử dụng các hàm bậc cao.Giá trị chức năng chung (Lỗi)

Trong ví dụ bên dưới, tôi có một đối tượng độc lập (Util) có một hàm. Nhưng trong khối Main, người gọi phải chuyển kiểu tham số cho hàm ẩn danh.

Tại sao Scala không phỏng đoán loại chức năng từ loại Array (tức là String)? Có cách nào để làm điều đó ?

object Util { 

// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length. 
// will swap the elements from arrayOne to ArrayTwo. 
    def swap[T](arrayOne:Array[T], arrayTwo:Array[T] , f:(T,T) =>(T,T)) { 
    for(i <- 0 until (arrayOne.length min arrayTwo.length)){ 
     val (left, right) = f(arrayOne(i),arrayTwo(i)) 
     arrayOne(i) = left 
     arrayTwo(i) = right 
    } 
    } 
} 

object Main extends Application { 

    val arrayOne = Array("A","B","C") 
    val arrayTwo = Array("D","E","F") 

//If not specified the type String,the compiler throws "Missing Parameter Type" error 

Util swap(arrayOne, arrayTwo,(elem1:String,elem2:String)=>(elem2,elem1)) 

} 
+0

Chỉ hoạt động đối với tôi a} trong đối tượng Util. –

+0

@Thomas nó hoạt động vì ông đã chỉ định loại trong hàm. :-) –

+0

@Daniel Chú thích loại là điều cuối cùng làm phiền tôi với mã này. Tôi tự hỏi nếu nó sẽ là thô lỗ để sửa chữa nó. Mất sự chú ý xuống dòng cuối cùng. –

Trả lời

14

Nó không suy ra các loại T vì điều duy nhất nó phải đi bởi vào thời điểm này sẽ là arrayOnearrayTwo. Tuy nhiên, Scala không sử dụng kiểu của một tham số để suy ra loại khác, có thể vì nó sẽ gây ra vấn đề với quá tải phương thức. Tuy nhiên, nó hoạt động nếu bạn cà ri nó:

Object Util { 

// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length. 
// will swap the elements from arrayOne to ArrayTwo. 
    def swap[T](arrayOne:Array[T], arrayTwo:Array[T])(f:(T,T) =>(T,T)) : Unit = { 
    var i = 0 
     var tuple :Tuple2[T,T] = null 
     while(i < arrayOne.length && i < arrayTwo.length){ 
     tuple =f(arrayOne(i),arrayTwo(i)) 
     arrayOne(i) = tuple._1 
     arrayTwo(i) = tuple._2 
     i+=1 
     } 
     } 
} 

object Main extends Application { 

    // val works fine below -- the object is mutable 
    val arrayOne = Array("A","B","C") 
    val arrayTwo = Array("D","E","F") 

    (Util swap(arrayOne, arrayTwo))((elem1,elem2)=>(elem2,elem1)) 
    // The weird parenthesis is caused by mixing operator notation and currying 
    // One could also write it like this: 
    // Util.swap(arrayOne, arrayTwo)((elem1,elem2)=>(elem2,elem1)) 
} 

Lý do tại sao nó hoạt động tốt nếu bạn cà ri nó là một phương pháp cà ri thực sự là một phương pháp nhận được danh sách tham số đầu tiên và trả về một chức năng mà đòi hỏi người kia (hoặc những người khác) danh sách tham số. Do đó, quá tải có thể được quyết định trong danh sách tham số đầu tiên, vì vậy danh sách tham số thứ hai có thể tận dụng các kiểu suy luận.

+0

Cảm ơn Daniel .. Thực sự thích câu trả lời của bạn! – CHAPa

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