( Bu soruya verdiğim yanıttan ilham aldım .)
Bu kodu göz önünde bulundurun (belirli bir girdiden küçük veya ona eşit olan en büyük öğeyi bulması gerekir):
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
Bu çok tembel değil. GT
Vaka girildikten sonra, nihai dönüş değerinin bundan Just
ziyade bir şey olacağını biliyoruz Nothing
, ancak Just
yine de sonuna kadar mevcut değil. O nedenle bu lazier yapmak istiyorum Just
en kısa sürede kullanılabilir GT
durumda girilir. Bunun için test durumum, dipten ziyade Data.Maybe.isJust $ closestLess 5 (Node 3 () Leaf undefined)
değerlendirmek istediğimdir True
. Bunu yapmayı düşünebileceğim bir yol var:
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
Ancak, şimdi kendimi tekrarlıyorum: çekirdek mantık şimdi hem içinde hem de closestLess
içinde precise
. Tembel olmak için kendimi tekrar etmeden nasıl yazabilirim?