( इस सवाल के मेरे जवाब से प्रेरित होकर ।)
इस कोड पर विचार करें (यह किसी दिए गए इनपुट से कम या उसके बराबर का सबसे बड़ा तत्व ढूंढना है):
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
। मैं इसे कैसे लिख सकता हूं ताकि यह आलसी हो लेकिन खुद को दोहराए बिना।