( 이 질문에 대한 나의 대답에서 영감을 얻었습니다 .)
이 코드를 고려하십시오 (주어진 입력보다 작거나 같은 가장 큰 요소를 찾아야합니다).
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
. 게으르지 만 반복하지 않도록 어떻게 작성할 수 있습니까?