ฉันสงสัยว่าการออกแบบที่ดีกว่าคืออะไรสำหรับการใช้งาน / การบำรุงรักษาและสิ่งที่ดีกว่าเท่าที่เหมาะสมกับชุมชน
รับรูปแบบข้อมูล:
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)
ฉันสามารถใช้ฟังก์ชั่น monadic เพื่อแปลงผู้ใช้ตัวอย่างโดยการเพิ่มรายการหรือร้านค้า ฯลฯ แต่ฉันอาจท้ายด้วยผู้ใช้ที่ไม่ถูกต้องดังนั้นฟังก์ชัน monadic เหล่านั้นจะต้องตรวจสอบความถูกต้องของผู้ใช้ที่พวกเขาได้รับและสร้าง
ดังนั้นฉันควร:
- ห่อไว้ในข้อผิดพลาด monad และทำให้ฟังก์ชัน monadic ดำเนินการตรวจสอบความถูกต้อง
- ห่อไว้ในข้อผิดพลาด monad และทำให้ผู้บริโภคผูกฟังก์ชันการตรวจสอบความถูกต้องตามลำดับที่ส่งการตอบสนองข้อผิดพลาดที่เหมาะสม (เพื่อให้พวกเขาสามารถเลือกที่จะไม่ตรวจสอบและพกพาวัตถุผู้ใช้ที่ไม่ถูกต้อง)
- จริง ๆ แล้วสร้างเป็นอินสแตนซ์ของการผูกบนผู้ใช้อย่างมีประสิทธิภาพในการสร้างข้อผิดพลาดของฉันเองชนิด monad ที่ดำเนินการตรวจสอบกับทุกผูกโดยอัตโนมัติ
ฉันสามารถเห็นข้อดีและข้อเสียของวิธีการทั้ง 3 วิธีนี้ แต่ต้องการทราบว่าชุมชนทำอะไรกันมากขึ้นสำหรับสถานการณ์นี้
ดังนั้นในแง่ของโค้ดอย่างตัวเลือก 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"]
ตัวเลือก 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)
ตัวเลือก 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"]