Trong Haskell, có một hàm "lấy danh sách n" trả về các phần tử n đầu tiên từ một danh sách. Ví dụ: "sum (take 3 xs)" tổng hợp ba phần tử đầu tiên trong danh sách xs. F # có tương đương không? Tôi mong đợi nó sẽ là một trong những chức năng Danh sách, nhưng tôi không thể phát hiện ra bất kỳ thứ gì có vẻ phù hợp.F # có tương đương với việc sử dụng của Haskell không?
Trả lời
Vâng, nó được gọi là Seq.take
. Cách sử dụng có vẻ giống hệt với số điện thoại của Haskell: Seq.take
tính nguồn.
Để sử dụng nó trên danh sách, trước tiên hãy sử dụng
(Cập nhật: Rõ ràng từ các ý kiến, điều này là không cần thiết.)List.toSeq
.
Để làm rõ một vài điều, sự khác biệt giữa Seq.take
và Seq.truncate
(như được chỉ ra bởi @ sepp2k) là một trong những thứ hai sẽ cung cấp cho bạn một chuỗi trả lại số tiền tối đa tối đa số phần tử bạn đã chỉ định (nhưng nếu độ dài của chuỗi ít hơn, nó sẽ cung cấp cho bạn ít phần tử hơn).
Trình tự tạo ra Seq.take
chức năng sẽ ném ngoại lệ nếu bạn cố truy cập phần tử vượt quá độ dài của danh sách gốc (Lưu ý rằng hàm Seq.take
không ném ngoại lệ ngay lập tức, vì kết quả là chuỗi được tạo lười biếng).
Ngoài ra, bạn không cần chuyển đổi danh sách thành chuỗi một cách rõ ràng. Dưới trang bìa, list<'a>
là lớp .NET kế thừa từ loại seq<'a>
, là giao diện. Loại seq<'a>
thực sự chỉ là một bí danh loại cho IEnumerable<'a>
, do đó, nó được thực hiện bởi tất cả các bộ sưu tập khác (bao gồm mảng, danh sách có thể thay đổi, v.v.). Các mã sau đây sẽ làm việc tốt:
let list = [ 1 .. 10 ]
let res = list |> Seq.take 5
Tuy nhiên, nếu bạn muốn có được một kết quả của loại list<int>
bạn sẽ cần phải chuyển đổi chuỗi lại một danh sách (vì một danh sách là loại hình cụ thể hơn một chuỗi):
let resList = res |> List.ofSeq
tôi không chắc chắn lý do tại sao F # thư viện không cung cấp List.take
hoặc List.truncate
. Tôi đoán mục tiêu là tránh thực hiện lại toàn bộ các chức năng cho tất cả các loại bộ sưu tập, vì vậy những nơi thực hiện chuỗi là đủ tốt khi làm việc với một loại bộ sưu tập cụ thể hơn chỉ có trong mô-đun Seq
(nhưng đó chỉ là phỏng đoán của tôi) ...)
Làm rõ rõ. – McMuttons
@McMuttons: Cảm ơn! Tôi không chắc mình có nên đăng nó hay không, bởi vì hầu hết mọi thứ đã được đề cập trong các ý kiến .. Vì vậy, tôi rất vui vì nó đã được sử dụng! –
Seq.take hoạt động, như những người khác đã nêu, nhưng tất cả các hoạt động Seq trên danh sách đều có tính phí. Trong trường hợp của Seq.take, nó không đáng ngạc nhiên, vì danh sách phải được sao chép.
Đáng chú ý hơn, ví dụ: Seq.concat trên danh sách mất nhiều thời gian hơn List.concat.
Tôi cho rằng điều đó ngụ ý rằng bạn không chỉ truy cập vào danh sách dưới dạng seq khi bạn gọi một hàm Seq.xxx, nhưng danh sách đó được sao chép/chuyển đổi thành một Seq đằng sau hậu trường.
chỉnh sửa: Lý do tôi đi đến kết luận trên, là băng ghế dự bị này sử dụng F # tương tác:
#time "on";;
let lists = [for i in 0..5000000 -> [i..i+1]];;
Seq.length (Seq.concat lists);;
List.length (List.concat lists);;
Trên máy tính của tôi, phiên bản List.length
mất khoảng 1,9 giây, trong khi phiên bản Seq.length
mất khoảng 3.8 giây (thời gian ngắn nhất của một vài phép thử lặp lại các dòng chiều dài, không bao gồm dòng tạo danh sách).
Tôi không nghĩ rằng điều này là chính xác. 'danh sách <'t>' triển khai giao diện 'seq <'t>' để không cần chuyển đổi, cũng không có lý do gì để mong đợi một bản sao được thực hiện. Ngoài ra, 'Seq.take' hoạt động một cách uể oải, trong khi' List.take' không thể, vì vậy trong một danh sách dài, các hoạt động chuỗi sẽ gần như chắc chắn sẽ nhanh hơn nếu chỉ có mặt trước của chuỗi kết quả là cần thiết. Tuy nhiên, có thể thực hiện một hàm 'List.take' thông qua kết hợp mẫu sẽ hoạt động tốt hơn so với triển khai' Seq.take' liệt kê danh sách nếu bạn muốn truy cập háo hức tất cả các phần tử trong danh sách kết quả. – kvb
Kết luận của tôi về các chuyển đổi diễn ra có thể là sai, nhưng có điều gì đó đang diễn ra và phải mất thêm thời gian. Tôi đã chỉnh sửa bài đăng của mình và thêm một số thời gian. – Batibix
- 1. Có F # tương đương với Lời hứa của Scala không?
- 2. Việc sử dụng tệp cấu hình có tương đương với việc sử dụng hình cầu không?
- 3. F # tương đương với số
- 4. Haskell tương đương với Boost.Fusion
- 5. Có tương đương với F # Seq.windowed trong C# không?
- 6. Có tương đương với việc tạo toán tử ngầm định C# trong F # không?
- 7. Haskell tương đương với scala thu thập
- 8. PowerShell tương đương với grep -f
- 9. Tương đương Haskell của C __LINE__
- 10. java tương đương với printf ("% *. * F")
- 11. Tương đương với phương thức Seq.scan() của F # bằng Python?
- 12. Tương đương với Python urllib trong Haskell
- 13. Vải tương đương trong Haskell?
- 14. "Curl -F" Java tương đương
- 15. Tương đương với Haskell do-notation hoặc F # Computation Expressions trong Scala?
- 16. Ruby có tương đương với việc sử dụng Perl nghiêm ngặt không?
- 17. F # Tương đương với Enumerable.OfType <'a>
- 18. F # List.map tương đương trong C#?
- 19. Tương đương với việc tiêm() bằng Python?
- 20. F # tương đương với `is` từ khóa trong C#?
- 21. Có tương đương C++ với BigDecimal của Java không?
- 22. C# có tương đương với mã encodeURIComponent của JavaScript() không?
- 23. Có Scala bất kỳ tương đương với Haskell không xác định?
- 24. F # tương đương với C# 'đối tượng' từ khóa
- 25. Tương đương TreeSet của Java tương đương với Python?
- 26. jquery có tương đương với dojo.hitch() không?
- 27. NotifyIcon có tương đương với MouseDown không?
- 28. Có Java tương đương với libevent không?
- 29. Có tương đương với idifierForVendor của iOS cho Android không?
- 30. C# tương đương với chức năng bản đồ trong Haskell
Điều đó dường như chính xác những gì tôi đang tìm kiếm. Thử nghiệm ngay bây giờ. :) – McMuttons
Thực ra, hành động của haskell có tác dụng như Seq.truncate, chứ không phải Seq.take. – sepp2k
Vì danh sách kế thừa từ IEnumerable, bạn không phải chuyển đổi nó thành chuỗi đầu tiên từ những gì tôi có thể thấy. Sử dụng Seq.take trên một danh sách làm việc tốt. – McMuttons