Hãy xem xét loại Ngày giờ trong đó ngày phải có, nhưng phần thời gian tính bằng giây là tùy chọn. Nếu phần thời gian ở đó, cũng có thể có một phần mili giây tùy chọn. Nếu có mili giây, có thể có một phần nano giây.Dữ liệu "Tùy chọn phụ thuộc" trong Haskell
Có nhiều cách để đối phó với điều này, ví dụ .:
--rely on smart constructors
data DateTime = DateTime { days:: Int,
sec :: Maybe Int,
ms :: Maybe Int,
ns :: Maybe Int
}
-- list all possibilities
data DateTime = DateOnly Int
| DateWithSec Int Int
| DateWithMilliSec Int Int Int
| DateWithNanoSec Int Int Int Int
-- cascaded Maybe
data DateTime = DateTime Int (Maybe (Int, Maybe (Int, Maybe Int)))
-- cascaded data
data Nano = NoNano | Nano Int
data MilliSec = NoMilliSec | MilliSec Int Nano
data Sec = NoSec | Sec Int MilliSec
data Date = Date Int Sec
nào xây dựng bạn sẽ sử dụng (tất nhiên không giới hạn ở các ví dụ trên), và tại sao?
[Intentions]
tôi đang khám phá các khả năng cho một loại ngày trong Frege (http://code.google.com/p/frege/), sử dụng date4j của DateTime
như một hướng dẫn dòng (như Haskell của ngày và thời gian lib là cách quá phức tạp, và java.util.Date
quá bị hỏng). Trong thực hiện đồ chơi hiện tại của tôi tất cả các trường là bắt buộc, nhưng tất nhiên nó sẽ được tốt đẹp để giải phóng người dùng từ độ chính xác không mong muốn (và thực hiện ban đầu có trường tùy chọn).
Vì vậy, mục tiêu chính là:
- an toàn: bang bất hợp pháp phải tránh bằng mọi giá
- tiện theo dõi: Nó phải là dễ dàng để làm việc với các loại, ví dụ khớp mẫu sẽ được mát mẻ, tính toán lịch nên dễ ...
Không phải như vậy quan trọng là:
- hiệu: Tất nhiên làm việc với các loại không nên quá chậm, nhưng đối với các điển hình sử dụng nó không cần phải trải ra chu kỳ đồng hồ cuối cùng
- bộ nhớ: Trong trường hợp điều này thực sự quan trọng, sẽ dễ dàng có được định dạng lưu trữ nhỏ gọn hơn
- triển khai thực hiện: Đó là thư viện và tôi sẵn sàng thêm tất cả mã cần thiết để làm cho mọi thứ trơn tru
Điều đó nói rằng, tất cả điều này là rất dự kiến và không nên quá nghiêm trọng.
Không chắc chắn điều này có thể trả lời mà không biết thêm về yêu cầu của bạn. Nó có thể phụ thuộc vào nhiều thứ, bao gồm những chức năng mà bạn dự định xác định về loại, hiệu suất và cân nhắc về không gian (số lượng các indirections, cơ hội để giải nén các trường, v.v.) – hammar
Một tùy chọn khác là sử dụng một hàm tạo đơn giản 'DateTime = DateTime [Int ] 'không được xuất từ thư viện và buộc tất cả tương tác với kiểu phải thông qua các hàm như' mkDateTimeWithSec :: [Int] -> DateTime', 'isDateTimeWithSec :: DateTime -> Bool',' getSeconds :: DateTime -> Có thể Int' vv Bạn không thể sử dụng mẫu phù hợp (nhưng có thể không quá khủng khiếp vì bạn chỉ cần thay thế bằng bảo vệ và sử dụng chức năng truy cập) nhưng bạn không cho phép người dùng tạo trạng thái bất hợp pháp, vì bạn có thể kiểm tra mọi thứ tại thời điểm xây dựng (ví dụ: bạn có thể kiểm tra các giá trị âm). –
Xác nhận ban đầu rằng dữ liệu không xác định là tùy chọn chứ không phải là mặc định làm cho một loại rất giả tạo - viết chức năng để thao tác nó sẽ là tẻ nhạt. Bạn cũng có thể có rác như một giá trị chỉ với nano giây nhưng không có gì giây. Tôi muốn thay đổi tack và làm việc cho dù mặc định 0 cho giá trị thời gian không xác định là bất lợi trong lý thuyết và thực hành. –