Tôi đang cố viết thư viện đo lường hiệu suất cho Scala. Ý tưởng của tôi là để minh bạch 'đánh dấu' phần để thời gian thực hiện có thể được thu thập. Thật không may tôi đã không thể uốn cong trình biên dịch theo ý muốn của tôi.Làm cách nào để tạo một hàm một phần với Generics trong Scala?
Một ví dụ phải thừa nhận là giả tạo về những gì tôi có trong tâm trí:
// generate a timing function
val myTimer = mkTimer('myTimer)
// see how the timing function returns the right type depending on the
// type of the function it is passed to it
val act = actor {
loop {
receive {
case 'Int =>
val calc = myTimer { (1 to 100000).sum }
val result = calc + 10 // calc must be Int
self reply (result)
case 'String =>
val calc = myTimer { (1 to 100000).mkString }
val result = calc + " String" // calc must be String
self reply (result)
}
Bây giờ, đây là xa nhất tôi nhận:
trait Timing {
def time[T <: Any](name: Symbol)(op: => T) :T = {
val start = System.nanoTime
val result = op
val elapsed = System.nanoTime - start
println(name + ": " + elapsed)
result
}
def mkTimer[T <: Any](name: Symbol) : (() => T) =>() => T = {
type c =() => T
time(name)(_ : c)
}
}
Sử dụng time
chức năng trực tiếp làm việc và trình biên dịch sử dụng một cách chính xác loại trả về của hàm ẩn danh để nhập hàm 'thời gian':
val bigString = time('timerBigString) {
(1 to 100000).mkString("-")
}
println (bigString)
lớn như nó có vẻ, mô hình này có một số thiếu sót:
- buộc người sử dụng để tái sử dụng các biểu tượng cùng một lúc mỗi lời gọi
- làm cho nó khó khăn hơn để làm công cụ tiên tiến hơn như giờ dự án cấp được xác định trước
- không cho phép thư viện để khởi tạo một lần một cấu trúc dữ liệu cho 'timerBigString
vì vậy, ở đây nói mkTimer, mà sẽ cho phép tôi để áp dụng một phần chức năng thời gian và tái sử dụng nó. Tôi sử dụng mkTimer như thế này:
val myTimer = mkTimer('aTimer)
val myString= myTimer {
(1 to 100000).mkString("-")
}
println (myString)
Nhưng tôi nhận được một lỗi biên dịch:
error: type mismatch;
found : String
required:() => Nothing
(1 to 100000).mkString("-")
tôi nhận được lỗi tương tự nếu tôi inline currying:
val timerBigString = time('timerBigString) _
val bigString = timerBigString {
(1 to 100000).mkString("-")
}
println (bigString)
này hoạt động nếu tôi làm val timerBigString = time('timerBigString) (_: String)
, nhưng đây không phải là những gì tôi muốn. Tôi muốn trì hoãn việc nhập chức năng được áp dụng một phần cho đến khi ứng dụng.
Tôi kết luận rằng trình biên dịch quyết định kiểu trả về của hàm một phần khi tôi tạo lần đầu tiên, chọn "Không có gì" vì nó không thể đưa ra lựa chọn sáng suốt hơn.
Vì vậy, tôi đoán những gì tôi đang tìm kiếm là một loại kết buộc muộn của hàm được áp dụng một phần. Có cách nào để làm điều này không? Hoặc có thể có một con đường hoàn toàn khác mà tôi có thể theo dõi?
Vâng, cảm ơn vì đã đọc đến đây
-teo
điểm trên! cảm ơn. –