2011-02-02 39 views
19

Từ các ngôn ngữ khác mà tôi lập trình, tôi đã từng có phạm vi. Trong Python, nếu tôi muốn tất cả các số một lên đến 100, tôi viết range(1, 101). Tương tự, trong Haskell tôi sẽ viết [1..100] và trong Scala tôi viết 1 to 100.Phạm vi ở Erlang

Tôi không thể tìm thấy nội dung nào đó tương tự trong Erlang, bằng cú pháp hoặc thư viện. Tôi biết rằng điều này sẽ khá đơn giản để thực hiện bản thân mình, nhưng tôi muốn chắc chắn rằng nó không tồn tại ở nơi khác đầu tiên (đặc biệt là kể từ khi một thư viện chuẩn hoặc thực hiện ngôn ngữ sẽ được tải hiệu quả hơn).

Có cách nào để thực hiện phạm vi trong ngôn ngữ Erlang hoặc thư viện chuẩn không? Hoặc là có một số thành ngữ mà tôi đang mất tích? Tôi chỉ muốn biết liệu tôi có nên tự mình thực hiện nó không.

Tôi cũng mở ra khả năng tôi không nên sử dụng phạm vi trong Erlang (tôi không muốn mã hóa Python hoặc Haskell trong Erlang). Ngoài ra, nếu tôi cần phải thực hiện điều này, nếu bạn có bất kỳ đề xuất tốt nào để cải thiện hiệu suất, tôi rất muốn nghe chúng :)

+0

Thật khó để nói bạn đang làm điều sai hay không. Bạn đã chỉ nói cách bạn đang cố gắng làm điều gì đó, không phải những gì bạn đang cố gắng làm. – Dustin

+0

@Dustin Tôi cho rằng ý tôi là tôi muốn biết nếu tôi không nghĩ mình nên ở Erlang. –

+0

Khi điểm btilly ra, danh sách: seq/2 là con đường để đi! Tôi thường có thể khuyên bạn nên xem xét các mô-đun danh sách, nó thực sự rất poweful. Oh, và nhìn vào http://www.erldocs.com –

Trả lời

45

Từ http://www.erlang.org/doc/man/lists.html có vẻ như bạn đang muốn lists:seq(1, 100). Bạn cũng có thể làm những việc như lists:seq(1, 100, 2) để nhận tất cả các số lẻ trong phạm vi đó thay thế.

+0

danh sách: seq/2 là phương pháp tốt nhất. – BlackMamba

8

Bạn có thể sử dụng list:seq(From, TO) mà nói @bitilly, và bạn cũng có thể sử dụng comprehensions danh sách để thêm nhiều chức năng hơn, ví dụ:

1> [X || X <- lists:seq(1,100), X rem 2 == 0]. 
[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42, 
44,46,48,50,52,54,56,58|...] 
2

Có sự khác biệt giữa phạm vi trong Ruby và danh sách: seq trong Erlang. Phạm vi của Ruby không tạo danh sách và dựa vào phương pháp tiếp theo, vì vậy (1..HugeInteger) .each {...} sẽ không ăn bộ nhớ. Danh sách Erlang: seq sẽ tạo danh sách (hoặc tôi tin rằng nó sẽ). Vì vậy, khi phạm vi được sử dụng cho các tác dụng phụ, nó tạo sự khác biệt.

P.S. Không chỉ cho các tác dụng phụ:

(1..HugeInteger).inject(0) { |s, v| s + v % 1000000 == 0 ? 1 : 0 } 

sẽ hoạt động giống như cách không tạo danh sách. Cách Erlang cho việc này là tạo ra một hàm đệ quy. Trong thực tế, nó là một vòng lặp che dấu anyway.

+0

Vâng, Erlang không có phương tiện để đánh giá lười biếng. –

+1

@Rafe Chắc chắn rồi! Chỉ cần sử dụng vui vẻ. –

+0

@Daniel nguyền rủa phán đoán ban đầu của tôi về ngôn ngữ. Tôi nên đọc thêm vào hướng dẫn. –

1

Ví dụ về luồng lười trong Erlang. Mặc dù nó không phải là Erlang cụ thể, tôi đoán nó có thể được thực hiện bằng bất kỳ ngôn ngữ nào với lambdas. Lambda mới được tạo ra mỗi khi luồng được nâng cao để nó có thể gây căng thẳng cho bộ thu gom rác.

range(From, To, _) when From > To -> 
    done; 
range(From, To, Step) -> 
    {From, fun() -> range(From + Step, To, Step) end}. 

list(done) -> 
    []; 
list({Value, Iterator}) -> 
    [Value | list(Iterator())]. 

% ----- usage example ------ 

list_odd_numbers(From, To) -> 
    list(range(From bor 1, To, 2)).