Tôi đang tự hỏi những gì thiết kế tốt hơn khôn ngoan cho khả năng sử dụng / bảo trì, và những gì tốt hơn khi phù hợp với cộng đồng.
Cho mô hình dữ liệu:
type Name = String
data Amount = Out | Some | Enough | Plenty deriving (Show, Eq)
data Container = Container Name deriving (Show, Eq)
data Category = Category Name deriving (Show, Eq)
data Store = Store Name [Category] deriving (Show, Eq)
data Item = Item Name Container Category Amount Store deriving Show
instance Eq (Item) where
(==) i1 i2 = (getItemName i1) == (getItemName i2)
data User = User Name [Container] [Category] [Store] [Item] deriving Show
instance Eq (User) where
(==) u1 u2 = (getName u1) == (getName u2)
Tôi có thể triển khai các chức năng đơn âm để chuyển đổi Người dùng chẳng hạn bằng cách thêm các mục hoặc cửa hàng, v.v., nhưng tôi có thể kết thúc với một người dùng không hợp lệ để các chức năng đơn nguyên đó cần xác thực người dùng họ nhận và tạo.
Vì vậy, tôi chỉ nên:
- bọc nó trong một đơn nguyên lỗi và làm cho các hàm đơn nguyên thực hiện xác nhận
- bọc nó trong một đơn vị lỗi và làm cho người tiêu dùng liên kết một chức năng xác thực đơn nguyên theo trình tự đưa ra phản hồi lỗi thích hợp (để họ có thể chọn không xác thực và mang theo một đối tượng người dùng không hợp lệ)
- thực sự xây dựng nó thành một cá thể liên kết trên Người dùng một cách hiệu quả tạo ra loại đơn lỗi của riêng tôi thực hiện xác thực với mọi liên kết tự động
Tôi có thể thấy những mặt tích cực và tiêu cực đối với mỗi trong số 3 cách tiếp cận nhưng muốn biết những gì thường được thực hiện cho kịch bản này bởi cộng đồng.
Vì vậy, trong thuật ngữ mã giống như, tùy chọn 1:
addStore s (User n1 c1 c2 s1 i1) = validate $ User n1 c1 c2 (s:s1) i1
updateUsersTable $ someUser >>= addStore $ Store "yay" ["category that doesnt exist, invalid argh"]
Lựa chọn 2:
addStore s (User n1 c1 c2 s1 i1) = Right $ User n1 c1 c2 (s:s1) i1
updateUsersTable $ Right someUser >>= addStore $ Store "yay" ["category that doesnt exist, invalid argh"] >>= validate
-- in this choice, the validation could be pushed off to last possible moment (like inside updateUsersTable before db gets updated)
tùy chọn 3:
data ValidUser u = ValidUser u | InvalidUser u
instance Monad ValidUser where
(>>=) (ValidUser u) f = case return u of (ValidUser x) -> return f x; (InvalidUser y) -> return y
(>>=) (InvalidUser u) f = InvalidUser u
return u = validate u
addStore (Store s, User u, ValidUser vu) => s -> u -> vu
addStore s (User n1 c1 c2 s1 i1) = return $ User n1 c1 c2 (s:s1) i1
updateUsersTable $ someValidUser >>= addStore $ Store "yay" ["category that doesnt exist, invalid argh"]