( इस सवाल के मेरे जवाब से प्रेरित होकर ।)
इस कोड पर विचार करें (यह किसी दिए गए इनपुट से कम या उसके बराबर का सबसे बड़ा तत्व ढूंढना है):
data TreeMap v = Leaf | Node Integer v (TreeMap v) (TreeMap v) deriving (Show, Read, Eq, Ord)
closestLess :: Integer -> TreeMap v -> Maybe (Integer, v)
closestLess i = precise Nothing where
precise :: Maybe (Integer, v) -> TreeMap v -> Maybe (Integer, v)
precise closestSoFar Leaf = closestSoFar
precise closestSoFar (Node k v l r) = case i `compare` k of
LT -> precise closestSoFar l
EQ -> Just (k, v)
GT -> precise (Just (k, v)) r
यह बहुत आलसी नहीं है। एक बार GTमामला दर्ज होने के बाद, हम यह सुनिश्चित करने के लिए जानते हैं कि अंतिम रिटर्न मूल्य Justइसके बजाय कुछ होगा Nothing, लेकिन Justअभी भी अंत तक उपलब्ध नहीं है। मैं यह लज़ीज़ बनाना चाहता हूँ ताकि केस दर्ज होते Justही उपलब्ध हो GT। इसके लिए मेरा परीक्षण मामला यह है कि मैं Data.Maybe.isJust $ closestLess 5 (Node 3 () Leaf undefined)मूल्यांकन करने के Trueबजाय नीचे करना चाहता हूं । यहाँ एक तरीका है जो मैं यह करने के लिए सोच सकता हूँ:
data TreeMap v = Leaf | Node Integer v (TreeMap v) (TreeMap v) deriving (Show, Read, Eq, Ord)
closestLess :: Integer -> TreeMap v -> Maybe (Integer, v)
closestLess _ Leaf = Nothing
closestLess i (Node k v l r) = case i `compare` k of
LT -> closestLess i l
EQ -> Just (k, v)
GT -> Just (precise (k, v) r)
where
precise :: (Integer, v) -> TreeMap v -> (Integer, v)
precise closestSoFar Leaf = closestSoFar
precise closestSoFar (Node k v l r) = case i `compare` k of
LT -> precise closestSoFar l
EQ -> (k, v)
GT -> precise (k, v) r
हालाँकि, मैं अब खुद को दोहरा रहा हूं: मुख्य तर्क अब और दोनों closestLessमें है precise। मैं इसे कैसे लिख सकता हूं ताकि यह आलसी हो लेकिन खुद को दोहराए बिना।