मैं सोच रहा हूं कि प्रयोज्यता / रखरखाव के लिए बेहतर डिज़ाइन वार क्या है, और समुदाय के साथ फिटिंग करने के लिए क्या बेहतर है।
डेटा मॉडल दिया:
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)
मैं उदाहरण के लिए आइटम या स्टोर आदि को जोड़कर उपयोगकर्ता को बदलने के लिए मोनैडिक फ़ंक्शंस लागू कर सकता हूं, लेकिन मैं एक अमान्य उपयोगकर्ता के साथ समाप्त हो सकता हूं, इसलिए उन राक्षसी कार्यों को उपयोगकर्ता को प्राप्त करने और बनाने या बनाने की आवश्यकता होगी।
तो, मैं बस चाहिए:
- इसे एक त्रुटि मोनड में लपेटें और मानदंड कार्यों को मान्यता निष्पादित करें
- इसे एक त्रुटि मोनाड में लपेटें और उपभोक्ता को इस क्रम में एक मोनिडिक सत्यापन फ़ंक्शन को बांधें जो उचित त्रुटि प्रतिक्रिया को फेंकता है (इसलिए वे अमान्य उपयोगकर्ता ऑब्जेक्ट को मान्य और ले जाने के लिए नहीं चुन सकते हैं)
- वास्तव में इसे उपयोगकर्ता पर एक बाँध उदाहरण में प्रभावी ढंग से बनाने के लिए अपनी तरह का त्रुटि मोनाद बना रहा है जो हर बाइंड के साथ सत्यापन को स्वचालित रूप से निष्पादित करता है
मैं 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"]