2011-08-26 32 views
7

Tôi đang gặp sự cố khi sử dụng hệ thống kiểu của Haskell một cách thanh lịch. Tôi chắc chắn rằng vấn đề của tôi là một vấn đề phổ biến, nhưng tôi không biết làm thế nào để mô tả nó ngoại trừ các thuật ngữ cụ thể cho chương trình của tôi.Đạt được sự trừu tượng phù hợp với hệ thống kiểu của Haskell

Các khái niệm Tôi đang cố gắng để biểu diễn là:

  • datapoints, mỗi trong số đó có một trong nhiều hình thức, ví dụ (id, số lượng các trường hợp, số lượng điều khiển), (id, số lượng các trường hợp, dân số)

  • bộ dữ liệu và thông tin tổng hợp: (bộ id, tổng số trường hợp, tổng số điều khiển), với các chức năng để thêm/loại bỏ điểm (vì vậy đối với từng nhiều điểm, có nhiều tương ứng của bộ)

tôi có thể có một lớp học của các loại điểm và xác định từng nhiều điểm as type riêng của mình. Ngoài ra, tôi có thể có một loại điểm và một hàm tạo dữ liệu khác nhau cho mỗi loại. Tương tự cho các tập hợp các điểm.

tôi có ít nhất một mối quan tâm với mỗi cách tiếp cận:

  • Với các lớp học kiểu: Tránh tên hàm va chạm sẽ gây phiền nhiễu. Ví dụ, cả hai loại điểm có thể sử dụng một hàm để trích xuất "số lượng các trường hợp", nhưng loại lớp không thể yêu cầu chức năng này bởi vì một số loại điểm khác có thể không có trường hợp.

  • Không có loại lớp: Tôi không muốn xuất các trình tạo dữ liệu từ mô-đun Point (cung cấp các hàm khác, an toàn hơn để tạo giá trị mới). Nếu không có các nhà xây dựng dữ liệu, tôi sẽ không thể xác định được giá trị điểm nào của một giống nào đó.

Thiết kế nào có thể giúp giảm thiểu những vấn đề này (và các vấn đề khác)?

+0

Trong hoàn cảnh nào bạn cần phải đối xử với các điểm dữ liệu của bạn tương tự? Bạn nói rằng mỗi mẫu sẽ cần nhiều tập hợp riêng của mình và các hoạt động như "số lượng các trường hợp" không phổ biến. –

Trả lời

4

Để mở rộng một chút về câu trả lời của sclv, có một gia đình mở rộng các khái niệm liên quan chặt chẽ đến việc cung cấp một số phương tiện phá hủy giá trị: Catamorphisms, là các nếp gấp chung; Mã hóa giáo hội, đại diện cho dữ liệu theo các phép toán của nó, và thường tương đương với việc áp dụng một phần sự biến hình đối với giá trị nó phá hủy; CPS biến đổi, trong đó một bảng mã Giáo Hội giống với một mô hình trùng khớp trùng lặp có các tiếp nối riêng biệt cho từng trường hợp; đại diện cho dữ liệu như một tập hợp các hoạt động sử dụng nó, thường được gọi là lập trình hướng đối tượng; và vân vân. Trong trường hợp của bạn, những gì bạn muốn là một kiểu trừu tượng , tức là không xuất bản biểu diễn bên trong của nó, nhưng không xuất hiện một biểu tượng bên trong, nghĩa là để biểu diễn mở cho các chức năng trong mô-đun định nghĩa nó. Đây là cùng một mẫu, theo sau là những thứ như Data.Map.Map.Bạn có thể không muốn đi tuyến đường loại lớp, vì có vẻ như bạn cần phải làm việc với nhiều điểm dữ liệu khác nhau, thay vì tùy chọn một loại dữ liệu duy nhất.

Rất có thể, một số kết hợp của "nhà thầu thông minh" để tạo giá trị và nhiều chức năng giải mã (như mô tả ở trên) được xuất từ ​​mô-đun là điểm bắt đầu tốt nhất. Đi từ đó, tôi hy vọng hầu hết các chi tiết còn lại sẽ có một cách tiếp cận rõ ràng để tiếp theo.

3

Với giải pháp thứ hai (không có lớp loại), bạn có thể xuất catamorphism vào loại chứ không phải là các nhà thầu ..

data MyData = PointData Double Double | ControlData Double Double Double | SomeOtherData String Double 

foldMyData pf cf sf d = case d of 
     (PointData x y) -> pf x y 
     (ControlData x y z) -> cf x y z 
     (SomeOtherData s x) -> sf s x 

Bằng cách đó bạn có một cách để kéo dữ liệu của bạn ngoài vào bất cứ điều gì bạn muốn (bao gồm chỉ bỏ qua các giá trị và các hàm truyền mà trả về kiểu constructor bạn đã sử dụng) mà không cung cấp cách tổng quát để xây dựng dữ liệu của bạn.

2

Tôi tìm cách tiếp cận dựa trên loại lớp tốt hơn miễn là bạn sẽ không kết hợp các điểm dữ liệu khác nhau trong một cấu trúc dữ liệu duy nhất.

Vấn đề tên va chạm mà bạn đề cập có thể được giải quyết bằng cách tạo ra một lớp học loại riêng biệt cho từng lĩnh vực riêng biệt, như thế này:

class WithCases p where 
    cases :: p -> NumberOfCases 
Các vấn đề liên quan