2009-05-18 44 views
6

Tôi vừa tìm thấy thứ tôi muốn gọi là "quirk" trong F # và muốn biết nó là do thiết kế hay nhầm lẫn và nếu nó được thiết kế thì tại sao lại như thế. .. Nếu bạn viết bất kỳ cụm từ nào trong đó cụm từ đầu tiên lớn hơn cụm từ thứ hai, chuỗi được trả về trống. Một cái nhìn phản xạ cho thấy điều này là do thiết kế, nhưng tôi không thể thực sự tìm thấy một lý do tại sao nó sẽ phải như vậy. Một ví dụ để tái tạo nó là:Dãy A đến B trong đó A> B trong F #


[1..10] |> List.length 
[10..1] |> List.length 

Việc đầu tiên sẽ in ra 10 trong khi thứ hai sẽ in ra 0. Các thử nghiệm đã được thực hiện trong F # CTP 1.9.6.2.

EDIT: cảm ơn vì đã gợi ý phạm vi, nhưng vẫn có một trường hợp (đó là điều khiến tôi đặt câu hỏi này) sẽ không được đề cập đến. Điều gì xảy ra nếu A và B là các biến và không có biến nào liên tục lớn hơn các biến khác mặc dù chúng luôn khác nhau? Xét rằng biểu thức phạm vi dường như không được tối ưu hóa ở thời gian được biên dịch, có lý do nào tốt cho mã xác định bước (không được chỉ định rõ ràng) trong trường hợp A và B không cho phép các bước phủ định không?

+1

Câu hỏi liên quan đến một số mã có thể quan tâm http://stackoverflow.com/questions/377078/f-floating-point-ranges-are-experimental-and-may-be-deprecated – Benjol

Trả lời

10

Theo đề nghị của câu trả lời khác, bạn có thể làm

[10 .. -1 .. 1] |> List.iter (printfn "%A") 

ví dụ

[start .. step .. stop] 
+0

Cảm ơn điều này, nhưng bạn có thể vui lòng xem/bình luận/trả lời chỉnh sửa của tôi không? Cảm ơn trước – em70

+0

Bạn luôn có thể viết hai (hoặc ba) chức năng đối số của riêng bạn để làm bất cứ điều gì bạn thích. Cú pháp viết tắt là, tôi nghĩ sử dụng 98% thời gian cho các trường hợp mà tất cả các giá trị là các giá trị theo nghĩa đen. Vào cuối ngày, tôi nghĩ rằng tất cả các lựa chọn thiết kế ngôn ngữ có thể trong không gian này là hợp lý và không ai nổi bật là khách quan tốt hơn những người khác trong ước tính của tôi. – Brian

+0

Tôi thực sự đã viết chức năng của riêng mình, nhưng ý tưởng rằng bước phủ định được xác định tự động bị chặn rõ ràng làm tôi lo lắng, xem xét nó sẽ khá trực quan với cú pháp cho biết phạm vi hỗ trợ tạo phạm vi hướng. – em70

1

Ranges thường được thể hiện (trong các ngôn ngữ và các khuôn khổ hỗ trợ chúng) như thế này:

low_value <to> high_value

Bạn có thể cho một cuộc tranh luận chính đáng tại sao một loạt nên để có thể được thể hiện khác nhau? Vì bạn đã yêu cầu một phạm vi từ một số cao hơn đến một số thấp hơn không phải vì lý do mà phạm vi kết quả sẽ không có thành viên?

+0

Trường hợp trong đó A và B là biến là một trường hợp đủ tốt theo ý kiến ​​của tôi ... – em70

2

Trong haskell, bạn có thể viết [10, 9 .. 1]. Có lẽ nó hoạt động tương tự trong F # (tôi đã không thử nó)?

chỉnh sửa:

Dường như # cú pháp F là khác nhau, có lẽ cái gì đó như [10..-1..1]

3

gì "nên" xảy ra là, tất nhiên, chủ quan. Ký pháp phạm vi bình thường trong tâm trí của tôi định nghĩa [x..y] là tập hợp của tất cả các phần tử lớn hơn hoặc bằng x AND nhỏ hơn hoặc bằng y; bộ trống nếu y < x. Trong trường hợp này, chúng ta cần khiếu nại đến thông số F #.

Biểu thức phạm vi expr1 .. expr2 được đánh giá là cuộc gọi đến toán tử quá tải (..), có liên kết mặc định được xác định trong Microsoft.FSharp.Core.Operators. Điều này tạo ra một IEnumerable < _> cho phạm vi giá trị giữa giá trị bắt đầu cho trước (expr1) và kết thúc (expr2), sử dụng gia số của 1. Toán tử yêu cầu sự tồn tại của một thành viên tĩnh (..) (tên dài GetRange) trên loại tĩnh của expr1 với chữ ký thích hợp.

Biểu thức phạm vi expr1 .. expr2 .. expr3 được đánh giá là cuộc gọi đến toán tử quá tải (.. ..), có liên kết mặc định được xác định trong Microsoft.FSharp.Core.Operators. Điều này tạo ra một số lượng truy cập IE2umerable < _> cho phạm vi của các giá trị giữa các giá trị bắt đầu cho trước (expr1) và kết thúc (expr3), sử dụng tăng expr2. Toán tử yêu cầu sự tồn tại của một thành viên tĩnh (..) (tên dài GetRange) trên kiểu tĩnh của expr1 với một chữ ký thích hợp.

Tiêu chuẩn dường như không xác định toán tử .. (ít nhất, tôi có thể tìm thấy).Nhưng bạn sẽ có thể thay đổi ràng buộc cho các loại bạn quan tâm để cư xử theo bất kỳ cách nào bạn thích (bao gồm đếm ngược nếu x> y).

3

Adam Wright - Nhưng bạn sẽ có thể để thay đổi các ràng buộc đối với các loại bạn quan tâm đến việc ứng xử trong bất kỳ cách nào bạn (bao gồm cả đếm ngược nếu x> y).

Lấy gợi ý của Adam vào mã:

let (..) a b = 
    if a < b then seq { a .. b } 
      else seq { a .. -1 .. b } 

printfn "%A" (seq { 1 .. 10 }) 
printfn "%A" (seq { 10 .. 1 }) 

này làm việc cho int dãy. Hãy xem mã nguồn cho (..): bạn có thể sử dụng để làm việc trên các loại phạm vi khác, nhưng không chắc chắn cách bạn sẽ nhận được giá trị đúng của -1 cho loại cụ thể của bạn.

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