2013-03-03 21 views
12

Có một lý do chính đáng cho một trật tự lập luận khác nhau trong các chức năng nhận được yếu tố N-thứ của Array, danh sách hoặc Seq:để lập luận khác nhau để có được yếu tố N-thứ của Array, danh sách hoặc Seq

Array.get source index 
List .nth source index 
Seq .nth index source 

tôi muốn sử dụng toán tử đường ống và dường như chỉ có thể với Seq:

s |> Seq.nth n 

Có cách nào để có cùng ký hiệu với Array hoặc List không?

Trả lời

15

Tôi không nghĩ ra bất kỳ lý do chính xác nào để xác định Array.getList.nth theo cách này. Cho rằng pipeplining là rất phổ biến trong F #, họ nên đã được xác định để các đối số source đến cuối cùng.

Trong trường hợp List.nth, nó không thay đổi nhiều vì bạn có thể sử dụng Seq.nth và thời gian phức tạp vẫn là O(n) nơi n là chiều dài của danh sách:

[1..100] |> Seq.nth 10 

Nó không phải là một ý tưởng tốt để sử dụng Seq.nth trên mảng vì bạn mất quyền truy cập ngẫu nhiên. Để giữ O(1) thời điểm Array.get chạy, bạn có thể định nghĩa:

[<RequireQualifiedAccess>] 
module Array = 
    /// Get n-th element of an array in O(1) running time 
    let inline nth index source = Array.get source index 

Nhìn chung, trình tự lập luận khác nhau có thể được giảm bớt bằng cách sử dụng flip chức năng:

let inline flip f x y = f y x 

Bạn có thể sử dụng nó trực tiếp trên các chức năng trên:

[1..100] |> flip List.nth 10 
[|1..100|] |> flip Array.get 10 

7

Chỉ cần sử dụng nhà điều hành đường ống ngược:

[1..1000] |> List.nth <| 42 

Kể từ khi cả hai nhà khai thác còn lại kết hợp, x |> f <| y được phân tách như (x |> f) <| y, và điều này làm các trick.

Nhà điều hành đường ống lạc hậu cũng hữu ích nếu bạn muốn xóa dấu ngoặc đơn: f (very long expression) có thể được thay thế bằng f <| very long expression.

+3

Nó thực hiện thủ thuật, nhưng tôi không thích khả năng đọc của nó - rất ngột ngạt! –

+0

@PaulJurczak Tuyệt đối, đó là một vấn đề về phong cách. Cá nhân, tôi yêu thích các toán tử, nhưng chúng tự nhiên có [hạn chế] (Fstackoverflow.com/a/12499093/974789) trong F #, vì vậy nó là một sự lựa chọn giữa 'flip', các phương thức mở rộng và' <| '. Có vẻ như không có ý tưởng nào tốt hơn. – bytebuster

+2

+1 'not' và' defaultArg' khiến tôi quen với việc sử dụng '<|'; nó không có vẻ khó xử như vậy một khi bạn quen với nó. – ildjarn

5

Vì Pad và bytebuster đã trả lời câu hỏi cuối cùng của bạn, tôi sẽ tập trung vào phần lý do.

Điều này dựa trên kiến ​​thức hiện tại của tôi chứ không dựa trên các sự kiện lịch sử.

Kể từ F # có nguồn gốc từ OCaml và OCaml có ArrayList nhưng not Seq và F # sử dụng |> cho pipelining tự nhiên và type checkingOCaml lacks the pipleline operator, các tác giả của F # thực hiện chuyển đổi cho Seq. Nhưng rõ ràng là compatablie lạc hậu với OCaml họ đã không chuyển đổi mọi thứ.

+0

Lý thuyết di sản OCaml tạo ra nhiều ý nghĩa. –

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