আপনার monadic ফাংশনগুলিতে বৈধতা সহ ত্রুটি মনাদ ব্যবহার করা বা আপনার নিজের মোনাডকে বৈধতার সাথে সরাসরি আপনার বাঁধাইতে প্রয়োগ করা ভাল?


9

আমি ভাবছি যে ব্যবহারযোগ্যতা / রক্ষণাবেক্ষণের জন্য আরও ভাল ডিজাইন বুদ্ধিমান কি না এবং সম্প্রদায়ের সাথে উপযুক্ত হিসাবে আরও ভাল।

ডেটা মডেল দেওয়া:

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 ফাংশনগুলি তাদের প্রাপ্ত ব্যবহারকারীকে এবং বৈধ করে তোলার প্রয়োজন হয় create

সুতরাং, আমি কি ঠিক:

  • এটিকে একটি ত্রুটি মোনাডে মোড়ানো করুন এবং মোনাদিক ফাংশনগুলি বৈধকরণ কার্যকর করুন
  • এটিকে একটি ত্রুটি মোনাডে আবদ্ধ করুন এবং ভোক্তাকে যথাযথ ত্রুটির প্রতিক্রিয়া ছুঁড়ে এমন ক্রমে একটি এককীয় বৈধতা ফাংশন বাঁধুন (যাতে তারা কোনও অবৈধ ব্যবহারকারীর অবধি বৈধতা না দিয়ে এবং বহন করতে পারে)
  • ব্যবহারকারী এটি কার্যকরভাবে আমার নিজস্ব ত্রুটি মোনাড তৈরি করে যা প্রতিটি বাইন্ডের সাথে বৈধতা স্বয়ংক্রিয়ভাবে কার্যকর করে কার্যকরভাবে এটি একটি বাঁধাই দৃষ্টান্ত হিসাবে তৈরি করে

আমি 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"]

উত্তর:


5

মুষ্টি আমি নিজেকে জিজ্ঞাসা করব: একটি অবৈধ Userকোড বাগ বা এমন একটি পরিস্থিতি রয়েছে যা সাধারণত ঘটতে পারে (উদাহরণস্বরূপ কেউ আপনার আবেদনে একটি ভুল ইনপুট প্রবেশ করিয়ে দিচ্ছে)। এটি যদি কোনও বাগ হয় তবে আমি তা নিশ্চিত করার চেষ্টা করব যে এটি কখনই না ঘটে (যেমন স্মার্ট কনস্ট্রাক্টর ব্যবহার করে বা আরও পরিশীলিত ধরণের তৈরি করা)।

যদি এটি কোনও বৈধ দৃশ্যের হয় তবে রানটাইম চলাকালীন কিছু ত্রুটি প্রক্রিয়াকরণ উপযুক্ত। তারপর আমি জিজ্ঞেস করবে না কি এটি সত্যিই আমার জন্য মানে একটি Userহল অবৈধ ?

  1. এর অর্থ কি এই যে কোনও অবৈধ Userকিছু কোড ব্যর্থ করতে পারে? আপনার কোডের কিছু অংশ Userকি সর্বদা বৈধ হয় এই সত্যের উপর নির্ভর করে ?
  2. বা এর অর্থ কি এটির একটি অসঙ্গতি যা পরে সংশোধন করা দরকার, তবে গণনার সময় কিছু ভাঙ্গেনি?

যদি এটি ১ হয়, আমি অবশ্যই কোনও ধরণের ত্রুটি মনোডের জন্য যাব (মানক বা আপনার নিজস্ব), অন্যথায় আপনি আপনার কোডটি সঠিকভাবে কাজ করছে কিনা তার গ্যারান্টিটি হারাবেন।

আপনার নিজের মোনাড তৈরি করা বা একটি স্ট্যাক মোনাড ট্রান্সফর্মার ব্যবহার করা অন্য একটি সমস্যা, সম্ভবত এটি সহায়ক হবে: বন্যের মধ্যে কেউ কখনও কোনও মোনাড ট্রান্সফর্মারটির মুখোমুখি হয়েছে?


আপডেট: আপনার প্রসারিত বিকল্পগুলি খুঁজছেন:

  1. যেতে সেরা উপায় হিসাবে দেখায়। সম্ভবত, সত্যিই নিরাপদ হওয়ার জন্য, আমি বরং এর নির্মাতাকে লুকিয়ে রেখেছি Userএবং এর পরিবর্তে কেবল কয়েকটি ফাংশন রফতানি করব যা কোনও অবৈধ উদাহরণ তৈরি করতে দেয় না। এইভাবে আপনি নিশ্চিত হন যে যে কোনও সময় এটি সঠিকভাবে পরিচালিত হয়। উদাহরণস্বরূপ, একটি তৈরির জন্য একটি জেনেরিক ফাংশন Userএমন কিছু হতে পারে

    user :: ... -> Either YourErrorType User
    -- more generic:
    user :: (MonadError YourErrorType m) ... -> m User
    -- Or if you actually don't need to differentiate errors:
    user :: ... -> Maybe User
    -- or more generic:
    user :: (MonadPlus m) ... -> m User
    -- etc.
    

    উদাহরণস্বরূপ Map, অনেক লাইব্রেরি অনুরূপ অ্যাপোপ্যাচ নেয় Setবা Seqঅন্তর্নিহিত বাস্তবায়নটি আড়াল করে রাখে যাতে কোনও কাঠামো তৈরি করা সম্ভব হয় না যা তাদের আক্রমণকারীদের আনুগত্য করে না।

  2. আপনি যদি বৈধকরণটি একেবারে শেষ পর্যন্ত স্থগিত করে থাকেন এবং Right ...সর্বত্র ব্যবহার করেন , আপনার আর কোনও মোনাডের দরকার নেই। আপনি খাঁটি গণনা করতে পারেন এবং শেষে যে কোনও সম্ভাব্য ত্রুটি সমাধান করতে পারেন। আইএমএইচও এই পদ্ধতিটি খুব ঝুঁকিপূর্ণ, কারণ একটি অবৈধ ব্যবহারকারীর মান অন্য কোথাও অবৈধ ডেটা বয়ে আনতে পারে কারণ আপনি খুব শীঘ্রই এই গণনাটি বন্ধ করেন নি। এবং, যদি এমন হয় যে অন্য কোনও পদ্ধতি ব্যবহারকারীকে আপডেট করে যাতে এটি আবার বৈধ হয়, আপনি কোথাও অবৈধ ডেটা রাখবেন এবং এমনকি এটি সম্পর্কে না জেনেও শেষ করবেন।

  3. এখানে বেশ কয়েকটি সমস্যা রয়েছে।

    • সর্বাধিক গুরুত্বপূর্ণটি হ'ল কোনও মোনাডকে অবশ্যই যে কোনও ধরণের প্যারামিটার গ্রহণ করতে হবে User। সুতরাং আপনার কোনও validateপ্রকার u -> ValidUser uবাধা ছাড়াই টাইপ করতে হবে u। সুতরাং এমন একটি মোনাদ লেখা সম্ভব নয় যা ইনপুটগুলিকে বৈধতা দেয় return, কারণ returnঅবশ্যই সম্পূর্ণ পলিমার্প্পিক হতে হবে।
    • এরপরে, আমি যা বুঝতে পারি না তা হ'ল case return u ofআপনি এর সংজ্ঞায় মেলে >>=। মূল পয়েন্টটি ValidUserবৈধ এবং অবৈধ মানগুলির মধ্যে পার্থক্য করা উচিত এবং সুতরাং মনোদাকে অবশ্যই নিশ্চিত করা উচিত যে এটি সর্বদা সত্য। সুতরাং এটি সহজভাবে হতে পারে

      (>>=) (ValidUser u) f = f u
      (>>=) (InvalidUser u) f = InvalidUser u
      

    এবং এটি ইতিমধ্যে খুব ভালো দেখাচ্ছে Either

সাধারণত, আমি যদি কাস্টম মোনাড ব্যবহার করি তবেই

  • আপনার প্রয়োজনীয় কার্যকারিতা সরবরাহ করার জন্য কোনও বিদ্যমান মনড নেই। বিদ্যমান মনডগুলিতে সাধারণত অনেকগুলি সাপোর্ট ফাংশন থাকে এবং আরও বড় কথা, তাদের কাছে মনাড ট্রান্সফর্মার রয়েছে যাতে আপনি তাদেরকে মোনাড স্ট্যাকগুলিতে রচনা করতে পারেন।
  • অথবা আপনার যদি এমন একটি মোনাডের দরকার হয় যা মোনাদ স্ট্যাক হিসাবে বর্ণনা করা খুব জটিল।

আপনার শেষ দুটি পয়েন্ট অমূল্য এবং আমি সেগুলি সম্পর্কে ভেবে দেখিনি! অবশ্যই আমি যে বিজ্ঞতার জন্য সন্ধান করছিলাম, আপনার চিন্তাভাবনা ভাগ করে নেওয়ার জন্য ধন্যবাদ, আমি অবশ্যই # 1 এর সাথে যাব!
জিমি হোফা

শেষ রাতে পুরো মডিউলটি বেঁধে রেখেছিলেন এবং আপনি ঠিক মারা গেছেন। আমি আমার বৈধতা পদ্ধতিটি বেশ কয়েকটি সংখ্যক কী সংযুক্তকারীগুলিতে পপ করেছিলাম যা আমি সমস্ত মডেল আপডেটগুলি করেছিলাম এবং এটি আসলে এর চেয়ে অনেক বেশি অর্থবোধ করে। আমি সত্যিই # 3 এর পরে যাব এবং এখন আমি দেখতে পাচ্ছি যে ... কীভাবে এই পদ্ধতির অমনোযোগী হত, তাই আমাকে সোজা সেট করার জন্য একটি টনকে ধন্যবাদ!
জিমি হোফা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.