2010-12-12 32 views
12

Reading "Real thế giới Haskell" tôi tìm thấy một số câu hỏi intresting về các kiểu dữ liệu:Haskell loại dữ liệu sử dụng practicies tốt

mô hình kết hợp này và vị trí truy cập dữ liệu làm cho nó trông giống như bạn có khớp nối rất chặt chẽ giữa các dữ liệu và mã hoạt động trên đó (hãy thử thêm thứ gì đó vào Sách hoặc tệ hơn là thay đổi loại của một phần hiện có).

Đây thường là một điều rất xấu trong bắt buộc (đặc biệt là OO) ngôn ngữ ... không được xem là vấn đề trong Haskell? source at RWH comments

Và thực sự, viết một số chương trình Haskell Tôi thấy rằng khi tôi thực hiện thay đổi nhỏ để cấu trúc kiểu dữ liệu nó ảnh hưởng đến hầu hết các chức năng mà sử dụng kiểu dữ liệu. Có thể có một số phương pháp hay để sử dụng loại dữ liệu. Làm thế nào tôi có thể giảm thiểu khớp nối mã?

Trả lời

13

Điều bạn mô tả thường được gọi là vấn đề biểu thức - http://en.wikipedia.org/wiki/Expression_Problem.

Có một thỏa thuận nhất định phải được thực hiện, mã haskell nói chung và các loại dữ liệu đại số nói riêng, có xu hướng rơi vào khó thay đổi loại nhưng dễ dàng thêm chức năng trên loại. Điều này tối ưu hóa cho (lên phía trước) được thiết kế tốt, đầy đủ, các loại dữ liệu.

Tất cả những gì đã nói, có một số điều bạn có thể làm để giảm khớp nối.

  • Xác định các chức năng thư viện tốt, bằng cách xác định bộ tổ hợp hoàn chỉnh và chức năng bậc cao hữu ích để tương tác với kiểu dữ liệu của bạn, bạn sẽ giảm khớp nối.Người ta thường nói rằng khi bạn nghĩ về mô hình phù hợp thì có một giải pháp tốt hơn bằng cách sử dụng các hàm bậc cao hơn. Nếu bạn tìm kiếm những tình huống này, bạn sẽ ở một vị trí tốt hơn.

  • Hiển thị cấu trúc dữ liệu của bạn dưới dạng các loại trừu tượng hơn. Điều này có nghĩa là thực hiện tất cả các loại lớp thích hợp. Điều này sẽ hỗ trợ định nghĩa một hàm thư viện vì bạn sẽ nhận được một bó miễn phí với bất kỳ lớp nào mà bạn triển khai thực hiện, ví dụ xem xét các thao tác trên Functor hoặc Monad.

  • Ẩn (càng nhiều càng tốt) bất kỳ nhà xây dựng kiểu nào. Các nhà xây dựng trình bày chi tiết triển khai và sẽ khuyến khích ghép nối. Gợi ý: liên kết này với việc xác định api tốt để tương tác với kiểu của bạn, người tiêu dùng kiểu của bạn hiếm khi, nếu bao giờ, phải sử dụng các hàm tạo kiểu.

Cộng đồng Haskell dường như đặc biệt giỏi trong việc này, nếu bạn nhìn vào rất nhiều các thư viện trên hackage bạn sẽ tìm thấy những ví dụ thực sự tốt thực hiện các lớp học kiểu và phơi bày các chức năng thư viện tốt.

+0

Tôi không nghĩ rằng bạn có thể hòa hợp mà không có sự phù hợp với mẫu. * Đệ quy rõ ràng * tuy nhiên hiếm khi cần thiết. – delnan

+0

+1 để đặt tên cho con thú. – fuz

7

Trước tiên, tôi muốn đề cập đến quan điểm của tôi, có hai loại khớp nối:

  • Một mà làm chấm dứt mã của bạn để biên dịch khi bạn thay đổi một và quên thay đổi khác

  • một mà làm cho buggy mã của bạn khi bạn thay đổi một và quên thay đổi khác

trong khi cả hai đều có vấn đề, nguyên là ít hơn đáng kể của ah eadache, và đó có vẻ là một trong những bạn đang nói về.

Tôi nghĩ rằng vấn đề chính bạn đang đề cập đến là do sử dụng quá nhiều đối số vị trí. Haskell gần như buộc bạn phải có các đối số vị trí trong các hàm bình thường của bạn, nhưng bạn có thể tránh chúng trong các sản phẩm kiểu của bạn (các bản ghi).

Chỉ sử dụng hồ sơ thay vì nhiều trường ẩn danh bên trong trình tạo dữ liệu và sau đó bạn có thể khớp mẫu bất kỳ trường nào bạn muốn, theo tên.

bad (Blah _ y) = ...

good (Blah{y = y}) = ...

Tránh quá sử dụng các bộ, đặc biệt là những ngoài 2-tuples, và tự do tạo các bản ghi/newtypes xung quanh điều cần tránh nghĩa vị trí.

+1

Cảm ơn bạn đã trả lời. Tôi không giống như cú pháp ghi vì tên trường trở thành toàn cầu trong mô-đun. Có lẽ có một số cách chữa trị? – aindl

+0

IMO phương pháp chữa trị có các mô-đun rất nhỏ :-) – Peaker

+0

@masterzim Vấn đề ô nhiễm không gian tên với bản ghi sẽ nhận hotfix trong phiên bản sắp tới của GHC, cho phép bạn cung cấp nhiều loại tên bản ghi giống nhau. nhận được miễn phí sẽ được chung trên các loại có lĩnh vực hồ sơ đó. – kqr

10

Ngoài những gì đang được nói:

Một cách tiếp cận thú vị là "scrap your boilerplate" phong cách xác định các chức năng trên các kiểu dữ liệu, mà làm cho sử dụng các chức năng chung (như trái ngược với mô hình kết hợp rõ ràng) để xác định các chức năng trên các nhà xây dựng của một kiểu dữ liệu. Nhìn vào các mẩu tin "scrap your boilerplate", bạn sẽ thấy các ví dụ về các hàm có thể đối phó với những thay đổi đối với cấu trúc của một kiểu dữ liệu.

Một phương pháp thứ hai, như Hibberd chỉ ra, là sử dụng nếp gấp, maps, mở ra, và combinators đệ quy khác, để xác định chức năng của mình. Khi bạn viết các hàm sử dụng các hàm bậc cao hơn, đôi khi những thay đổi nhỏ đối với kiểu dữ liệu cơ bản có thể được xử lý trong các khai báo cá thể cho Functor, Có thể gập lại, v.v.

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