2013-04-12 31 views
15

Tôi đọc một bài báo về chương trình lệ thuộc, đánh máy và đi qua đoạn trích sau đây:Extensible Haskell Loại Lớp

"[...] trái ngược với các lớp học kiểu Haskell, kiểu dữ liệu [...] là đóng ", theo nghĩa là người ta không thể thêm các kiểu mới vào vũ trụ mà không mở rộng kiểu dữ liệu.

Câu hỏi mới của tôi là: theo nghĩa nào là các loại lớp Haskell mở? Chúng có thể mở rộng ra sao? Ngoài ra, các loại hậu quả lý thuyết của việc có tài sản này (mở vs đóng) là gì?

Cảm ơn bạn!

Trả lời

9

Cho một lớp kiểu như:

class Monoid m where 
    mempty :: m 
    mappend :: m -> m -> m 

... nó là (cơ bản) thực hiện dưới mui xe là một loại từ điển:

data Monoid m = Monoid 
    { mempty :: m 
    , mappend :: m -> m -> m 
    } 

Instances như:

instance Monoid [a] where 
    mempty = [] 
    mappend = (++) 

... được dịch sang từ điển:

listIsAMonoid :: Monoid [a] 
listIsAMonoid = Monoid 
    { mempty = [] 
    , mappend = (++) 
    } 

... và trình biên dịch tham khảo trên từ điển bất cứ khi nào bạn sử dụng danh sách với dung lượng là Monoid s.

này đưa chúng ta đến câu hỏi của bạn:

trong những gì có ý nghĩa là các lớp học kiểu Haskell mở? Chúng có thể mở rộng ra sao?

Chúng mở theo cùng nghĩa là các giá trị đa hình được mở. Chúng tôi có một số kiểu dữ liệu đa hình:

data Monoid m = ... 

... và chúng tôi có thể nhanh chóng biến m kiểu đa hình cho bất kỳ loại nơi chúng tôi có thể cung cấp các giá trị thích hợp cho các lĩnh vực memptymappend.

+0

Cách diễn giải kiểu lớp-như-từ điển là khá ghc-cụ thể. Không có gì trong thông số haskell yêu cầu nó và các triển khai khác (ví dụ: jhc) sử dụng một cách tiếp cận khác. –

+0

@JohnL Nó vẫn là một công cụ tinh thần hữu ích để hiểu được ý nghĩa trong đó nó là đa hình. –

12

Loại lớp học mở, bởi vì bạn có thể tạo kiểu tùy ý một thể hiện của nó. Khi bạn tạo loại lớp bạn chỉ định giao diện, nhưng không phải là loại thuộc về nó. Sau đó, trong bất kỳ mã nào bao gồm định nghĩa typeclass, bạn có thể làm cho thể hiện kiểu của nó cung cấp các hàm cần thiết từ giao diện sử dụng cú pháp instance TypeClass type of.

+1

Cảm ơn bạn đã trả lời. Tôi đã có giao diện/thực hiện trực giác trước đây. Câu hỏi của tôi là về việc liệu sau này có thể mở rộng giao diện được đưa ra bởi loại lớp, tức là bằng cách xác định một hàm tạo khác cho kiểu dữ liệu đó ngoài phạm vi ban đầu? – AnaK

+0

Bạn có thể mở rộng giao diện bằng cách xác định loại lớp mới chỉ, tuy nhiên có khái niệm về thừa kế cho phép bạn mở rộng nó. Bạn có thể sử dụng 'class (Interface BetterInterface) => BetterInterface type ở đâu ...'. So sánh cách 'Monad' có thể được triển khai dưới dạng phần mở rộng của' Functor'. – Adrian

+0

OK, tôi hiểu. Tôi đã suy nghĩ nhiều hơn dọc theo dòng ** mở ** loại dữ liệu được như vậy mà các nhà thầu của họ có thể xuất hiện rải rác, trong khi ngữ nghĩa hành động như thể họ đã bị đóng cửa (được xác định tại một nơi). – AnaK

2

Ralf Laemmel có một số rất tốt video lectures on Channel9 về điều này - rất khuyến khích.

+0

Cảm ơn bạn đã tham khảo! Tôi không biết về vấn đề biểu hiện. – AnaK

3

Loại lớp học là "mở" vì chúng luôn có thể có nhiều loại được thêm vào chúng "sau khi thực tế" bằng cách thêm các khai báo cá thể khác. Điều này thậm chí có thể được thực hiện trong mã "khách hàng" chỉ đơn thuần là sử dụng mô-đun có chứa loại loại. Điểm mấu chốt là tôi có thể viết mã hoạt động trên các giá trị với một số ràng buộc kiểu lớp, và cùng một mã không sửa đổi có thể được sử dụng trên các kiểu không tồn tại khi tôi viết lớp kiểu.

Các loại dữ liệu cụ thể trong Haskell được "đóng" ở chỗ điều này không thể xảy ra. Nếu tôi viết mã hoạt động trên các thành viên một loại dữ liệu cụ thể (ngay cả khi nó đa hình), thì không có cách nào bạn có thể sử dụng mã đó để hoạt động trên các loại điều mới mà tôi đã không nghĩ đến trừ khi bạn có thể sửa đổi loại (mà sau đó có thể yêu cầu sửa đổi tất cả các nơi mà nó được sử dụng).

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