इन कठिन गणित समस्याओं के लिए सही दृष्टिकोण एक डीएसएल है। इसलिए मैं इसे सरल भाषा के रूप में मॉडल करूँगा
data DSL b a = Var x (b -> a)
| Mult DSL DSL (b -> a)
| Plus DSL DSL (b -> a)
| Const Integer (b -> a)
हमारे DSL को अच्छी तरह से लिखने के लिए, इसे बीजगणितीय फ़नकार द्वारा उत्पन्न एक मुफ्त मोनाड के रूप में देखना उपयोगी है
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
और फिर एएसटी का पुनर्मूल्यांकन करना सीधा है।