2012-04-15 4 views
13

Làm cách nào để thêm kiểm tra đầu vào cho các nhà xây dựng dữ liệu Haskell? Giả sử tôi cóKiểm tra đầu vào trong các nhà xây dựng dữ liệu Haskell

import Data.Time.Calendar 

data SchedulePeriod = SchedulePeriod { startDate :: Day 
    , endDate :: Day 
    , accrualStart :: Day 
    , accrualEnd :: Day 
    , resetDate :: Day 
    , paymentDate :: Day 
    , fraction :: Double } 
    deriving (Show) 

và tôi muốn áp đặt ràng buộc startDate < endDate. Có cách nào để làm điều đó mà không tạo ra một kiểu dữ liệu trừu tượng?

+0

bản sao có thể có của [Cách tạo loại có hạn chế] (http://stackoverflow.com/questions/7978191/how-to-make-a-type-with-restrictions) – ehird

Trả lời

17

Cách tiêu chuẩn là sử dụng smart constructor để kiểm tra điều kiện tiên quyết trước khi tạo giá trị và không xuất bộ tạo thực mà nó sử dụng. Tất nhiên, điều này đang tạo ra một kiểu dữ liệu trừu tượng, như bạn đã nói.

Cách duy nhất để đạt được điều này mà không có một nhà xây dựng thông minh sẽ là thực sự tin tặc loại hệ thống ác (và bạn sẽ không thể sử dụng loại tiêu chuẩn Day).

+0

Tôi có thể sử dụng thông số được đặt tên trong thông minh không nhà thầu? –

+0

Nếu bạn có nghĩa là bắt chước cú pháp ghi, thì tiếc là không. Tuy nhiên, bạn có thể xác định một bản ghi khác để làm đầu vào cho hàm tạo thông minh. Điều đó có lẽ chỉ đáng giá nhân bản nếu hàm tạo của bạn làm điều gì đó hơn là xác thực đầu vào, mặc dù (ví dụ:tính toán các lĩnh vực phụ trợ). – ehird

+3

@quant_dev Nếu lý do bạn không muốn kiểu dữ liệu trừu tượng là bạn có thể ghép mẫu trên các hàm tạo, bạn có thể thực hiện hai hàm tạo thông minh và thực hiện các trình phá hủy thông minh (tương tự 'có thể' và' hoặc'). –

13

Chấp nhận câu trả lời của ehird. Tôi chỉ viết điều này để tôi có thể giải thích các destructor thông minh tôi đã đề cập trong một bình luận và tôi không thể phù hợp với lời giải thích trong một bình luận.

Hãy nói rằng bạn có các loại:

data T x y z = A | B x | C y z 

ehird đã giải thích làm thế nào để tóm tắt đi các nhà xây dựng, mà chỉ là cung cấp cho nhà xây dựng "thông minh". Như bạn đã đề cập, điều này đòi hỏi phải ẩn các nhà xây dựng và sau đó bạn không thể sử dụng chúng để phù hợp với mẫu. Tuy nhiên, bạn có thể giải quyết điều này bằng cách sử dụng một destructor "thông minh", tương đương với mô hình phù hợp với tất cả các nhà xây dựng có thể.

Để giải thích điều này, trước tiên hãy bắt đầu với cách chúng tôi muốn viết một chức năng của loại T nếu các nhà thầu đã được tiếp xúc:

myFunction :: T x y z -> d 
myFunction t = case t of 
    A  -> f1 
    B x -> f2 x 
    C y z -> f3 y z 

Chúng ta biết từ chữ ký kiểu của hàm các loại f1, f2, và f3 phải:

f1 :: d 
f2 :: x -> d 
f3 :: y -> z -> d 

Vì vậy, nếu chúng ta có thể khái quát myFunction là một destructor thông minh, chúng ta chỉ cần vượt qua f1, f2, và f3 như tham số cho nó:

smartDestructor :: d -> (x -> d) -> (y -> z -> d) -> t -> d 
smartDestructor f1 f2 f3 t = case t of 
    A  -> f1 
    B x -> f2 x 
    C y z -> f3 y z 

Vì vậy, nếu bạn xuất smartDestructor, sau đó mọi người có thể về cơ bản mô hình trận đấu chống lại loại của bạn mà không cần phải truy cập vào các nhà xây dựng.

Nếu bạn đã từng sử dụng các maybe hoặc either chức năng, trước đó, sau đó bạn đã sử dụng một destructor thông minh, mặc dù trong những trường hợp các nhà thầu không phải là ẩn, vì vậy họ chủ yếu được cung cấp như các chức năng tiện theo dõi:

maybe :: b -> (a -> b) -> Maybe a -> b 
maybe f1 f2 m = case m of 
    Nothing -> f1 
    Just a -> f2 x 

either :: (a -> c) -> (b -> c) -> Either a b -> c 
either f1 f2 e = case e of 
    Left a -> f1 a 
    Right b -> f2 b 

Trong trường hợp của bạn, mục đích của phá hủy thông minh chỉ là để bạn có thể ẩn các nhà xây dựng và không để lộ các nhà xây dựng.

+0

Cảm ơn, rất khai sáng. Tôi ước tôi có thể chấp nhận hai câu trả lời ... –

+3

@quant_dev Tôi vừa học được rằng có một cái tên tốt hơn cho "destructor thông minh". Nó được gọi là "nhà thờ mã hóa" các loại dữ liệu và nó đề cập đến một thực tế là bất kỳ loại dữ liệu có thể được đại diện như là một chức năng, và mã hóa chức năng này được gọi là "nhà thờ mã hóa". Để có một lời giải thích thực sự tốt, hãy kiểm tra liên kết này: http://web.archiveorange.com/archive/v/nDNOvgzSRV6TNq8KhCgZ –

+0

Cảm ơn, tôi sẽ đọc nó. –