2008-11-06 24 views
18

Trong bản đồ Python() hoạt động trên bất kỳ dữ liệu nào tuân theo giao thức trình tự. Nó làm điều đúng^TM cho dù tôi ăn nó một chuỗi hoặc một danh sách hoặc thậm chí một tuple.OCaml có các hàm map()/reduce() chung không?

Tôi cũng không thể có bánh trong OCaml? Tôi thực sự không có lựa chọn nào khác ngoài việc xem loại bộ sưu tập mà tôi đang sử dụng và tìm một List.map tương ứng hoặc một Array.map hoặc một Buffer.map hoặc một String.map? Một số trong số này thậm chí không tồn tại! Là những gì tôi yêu cầu cho bất thường? Chắc chắn là tôi đang thiếu gì đó.

+0

Vì vậy, chính xác điều gì là sai khi phải tra cứu tài liệu và sử dụng chức năng thích hợp? –

Trả lời

17

Gần nhất bạn sẽ nhận được đây là mô-đun Enum trong OCaml Batteries Included (trước đây là Extlib). Enum xác định bản đồ và nếp gấp trên Enum.t; bạn chỉ cần sử dụng chuyển đổi đến/từ Enum.t cho kiểu dữ liệu của mình. Các chuyển đổi có thể khá nhẹ, bởi vì Enum.t là lười.

Điều bạn thực sự muốn là kiểu Haskell type classes, như FoldableFunctor (tổng quát "bản đồ"). Thư viện Haskell xác định các trường hợp của FoldableFunctor cho danh sách, mảng và cây. Một kỹ thuật khác có liên quan là "Scrap Your Boilerplate" approach để lập trình chung. Vì OCaml không hỗ trợ các lớp kiểu hoặc higher-kinded polymorphism, tôi không nghĩ bạn có thể thể hiện các mẫu như thế này trong hệ thống kiểu của nó.

+0

Trong ML, hệ thống mô-đun bậc cao giải quyết vấn đề này. –

+0

Tôi không đồng ý rằng tất cả mọi thứ gói trong một functor là một "giải pháp" cho vấn đề này. –

+0

Bạn không đồng ý với thực tế.Hãy xem cuốn sách của Okasaki để biết nhiều ví dụ và so sánh giải thích tại sao giải pháp của OCaml lại thích hợp hơn khi nhập các lớp trong ngữ cảnh này. –

1

Vấn đề là mỗi vùng chứa có một biểu diễn khác nhau và yêu cầu mã khác nhau cho bản đồ/giảm để lặp qua nó. Đây là lý do tại sao có các chức năng riêng biệt. Hầu hết các ngôn ngữ cung cấp một số loại giao diện chung cho các thùng chứa (như giao thức trình tự mà bạn đã đề cập) để các chức năng như bản đồ/giảm có thể được triển khai một cách trừu tượng, nhưng điều này không được thực hiện cho các loại bạn đã đề cập.

-3

Miễn là bạn xác định loại so sánh t và val (: t-> t-> int) trong mô-đun của bạn, Map.Make sẽ cung cấp cho bạn bản đồ bạn muốn.

10

Có hai giải pháp chính trong OCaml:

  1. Jacques Garrigue đã thực hiện một cú pháp ánh sáng nhưng cách tiếp cận hiệu quả đối với nhiều cấu trúc dữ liệu cách đây vài năm. Bạn chỉ cần bọc các bộ sưu tập trong các đối tượng cung cấp phương thức map. Sau đó, bạn có thể làm collection#map để sử dụng chức năng bản đồ cho bất kỳ loại bộ sưu tập nào. Đây là tổng quát hơn yêu cầu của bạn bởi vì nó cho phép các loại cấu trúc dữ liệu khác nhau được thay thế tại thời gian chạy. Tuy nhiên, điều này không phải là rất hữu ích trong thực tế vì vậy cách tiếp cận không bao giờ được áp dụng rộng rãi.

  2. Giải pháp về cú pháp mạnh mẽ nhưng hiệu quả, mạnh mẽ và tĩnh là sử dụng các trình thu thập thông tin để tham số hóa mã của bạn qua cấu trúc dữ liệu bạn đang sử dụng. Điều này làm cho nó tầm thường để sử dụng lại mã của bạn với các cấu trúc dữ liệu khác nhau. Xem bản dịch OCaml của Markus Mottl về cuốn sách của Okasaki "Cấu trúc dữ liệu chức năng thuần túy" cho một số ví dụ tuyệt vời.

Nếu bạn không tìm kiếm loại sức mạnh đó và chỉ muốn ngắn gọn, tất nhiên, bạn chỉ có thể tạo bí danh mô-đun có tên ngắn hơn (ví dụ: S = String).

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