【发布时间】:2019-12-14 17:29:34
【问题描述】:
(灵感来自我对this question 的回答。)
考虑这段代码(它应该找到小于或等于给定输入的最大元素):
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 直到最后仍然不可用。我想让这个更懒惰,以便在输入GT 案例后立即使用Just。我对此的测试用例是我希望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 中。我怎样才能写出这样它是懒惰的,但又不重复自己?
【问题讨论】:
标签: haskell lazy-evaluation dry