2008-10-28 32 views

Trả lời

22

Không có thành ngữ mà tôi biết, nhưng đây là một định nghĩa khá tự nhiên sử dụng một nhà điều hành ghi:

# let (--) i j = 
    let rec aux n acc = 
     if n < i then acc else aux (n-1) (n :: acc) 
    in aux j [] ;; 
     val (--) : int -> int -> int list = <fun> 
# 1--2;; 
- : int list = [1; 2] 
# 1--5;; 
- : int list = [1; 2; 3; 4; 5] 
# 5--10;; 
- : int list = [5; 6; 7; 8; 9; 10] 

Ngoài ra, comprehensions syntax extension (mà cung cấp cho các cú pháp [i .. j] cho ở trên) có khả năng là bao gồm trong bản phát hành tương lai của "community version" of OCaml, để có thể trở thành thành ngữ. Tôi không khuyên bạn nên bắt đầu chơi với các phần mở rộng cú pháp nếu bạn chưa quen với ngôn ngữ.

+0

liên kết của bạn với cộng đồng ocaml phải trỏ đến: http://forge.ocamlcore.org/projects/batteries/ – Thelema

+0

Toán tử '--' được triển khai trong Pin Được bao gồm, mặc dù nó tạo ra enum chứ không phải danh sách. –

+0

Chức năng phạm vi của Python không bao gồm giới hạn trên, như của bạn, nhưng dễ dàng sửa chữa bằng cách gọi aux với (j-1) thay vì j –

10

Ở đây bạn đi:

let rec range i j = if i > j then [] else i :: (range (i+1) j) 

Lưu ý rằng đây không phải là đuôi-đệ quy. Các phiên bản Python hiện đại thậm chí có một phạm vi lười biếng.

+3

Không hoàn toàn - Phạm vi Python (1,3) trả về [1,2] trong khi (phạm vi 1 3) của bạn trả về [1; 2; 3]. Thay đổi> thành> =. –

0

BTW, trong Haskell bạn muốn sử dụng

enumFromTo 1 n 
[1 .. n] 

Đây chỉ là không cần thiết.

take n [1 ..] 
take n $ iterate (+1) 1 
+0

Cảm ơn, tôi đã không nhận ra điều đó. – Pramod

11

Với Batteries Included, bạn có thể viết

let nums = List.of_enum (1--10);; 

Nhà điều hành -- tạo ra một đếm từ giá trị đầu tiên vào thứ hai. Toán tử --^ tương tự, nhưng liệt kê khoảng thời gian nửa mở (1--^10 sẽ liệt kê từ 1 đến 9).

+0

Không chắc chắn tôi thích - vì điều đó, có thể xác định toán tử .. không? – aneccodeal

+1

@aneccodeal No. OCaml không cho phép các toán tử bắt đầu bằng '.' (mặc dù chúng có thể chứa '.' sau ký tự đầu tiên). Các ký tự được phép cho các toán tử được định nghĩa trong tài liệu từ vựng của OCaml tại đây: http://caml.inria.fr/pub/docs/manual-ocaml/lex.html –

2

Nếu bạn sử dụng open Batteries (là phiên bản cộng đồng của thư viện chuẩn), bạn có thể làm range(1,n+1) bằng cách List.range 1 `To n (chú ý báo trước trước To).

Một cách tổng quát hơn (cũng cần pin) là sử dụng List.init n f trả về danh sách chứa (f 0) (f 1) ... (f (n-1)).

3

OCaml có cú pháp đặc biệt cho phù hợp với mô hình trên phạm vi:

let() = 
    let my_char = 'a' in 
    let is_lower_case = match my_char with 
    | 'a'..'z' -> true (* Two dots define a range pattern *) 
    | _ -> false 
    in 
    printf "result: %b" is_lower_case 

Để tạo một phạm vi, bạn có thể sử dụng Core:

List.range 0 1000 
2

Một chút muộn để các trò chơi ở đây nhưng đây là thực hiện của tôi:

let rec range ?(start=0) len = 
    if start >= len 
    then [] 
    else start :: (range len ~start:(start+1)) 

Sau đó, bạn có thể sử dụng nó rất giống với hàm python:

range 10 
    (* equals: [0; 1; 2; 3; 4; 5; 6; 7; 8; 9] *) 

range ~start:(-3) 3 
    (* equals: [-3; -2; -1; 0; 1; 2] *) 

tự nhiên Tôi nghĩ câu trả lời tốt nhất là chỉ sử dụng Core, nhưng điều này có thể tốt hơn nếu bạn chỉ cần một chức năng và bạn đang cố gắng tránh toàn bộ khuôn khổ.

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