এই কঠিন গণিত সমস্যার জন্য সঠিক পদ্ধতির একটি ডিএসএল। সুতরাং আমি এটি একটি সাধারণ ভাষার ক্ষেত্রে মডেল করব
data DSL b a = Var x (b -> a)
| Mult DSL DSL (b -> a)
| Plus DSL DSL (b -> a)
| Const Integer (b -> a)
আমাদের ডিএসএলকে সুন্দরভাবে লিখতে, এটি বীজগণিতীয় ফান্টেক্টর দ্বারা উত্পাদিত একটি মুক্ত মনড হিসাবে দেখতে সহায়ক
F X = X + F (DSL b (F X)) -- Informally define + to be the disjoint sum of two sets
আমরা হাস্কেল হিসাবে এটি লিখতে পারে
Free b a = Pure a
| Free (DSL b (Free b a))
এর তুচ্ছ বাস্তবায়নটি পাঠকের কাছে ছেড়ে দেব
join :: Free b (Free b a) -> Free b a
return :: a -> Free b a
liftF :: DSL b a -> Free b a
এখন আমরা এই ডিএসএলে একটি ফ্যাকটোরিয়াল মডেল করার জন্য একটি অপারেশনকে মেনে নিতে পারি
factorial :: Integer -> Free Integer Integer
factorial 0 = liftF $ Const 1 id
factorial n = do
fact' <- factorial (n - 1)
liftF $ Mult fact' n id
এখন আমরা এটি মডেল করেছি, আমাদের কেবল আমাদের মুক্ত মোনাডের জন্য একটি আসল ব্যাখ্যা ফাংশন সরবরাহ করা দরকার।
denote :: Free Integer Integer -> Integer
denote (Pure a) = a
denote (Free (Const 0 rest)) = denote $ rest 0
...
এবং বাক্য নির্ধারণের বাকী অংশটি পাঠকের কাছে রেখে দেব।
পঠনযোগ্যতা উন্নত করতে, কখনও কখনও ফর্মের একটি কংক্রিট এএসটি উপস্থাপন করতে সহায়ক
data AST = ConstE Integer
| PlusE AST AST
| MultE AST AST
এবং তারপরে একটি তুচ্ছ প্রতিচ্ছবি ডানদিকে দিন
reify :: Free b Integer -> AST
এবং তারপরে এটিএসটির পুনরাবৃত্তির সাথে মূল্যায়ন করা সোজা।