Here's how I'd do it:

```
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
```

A few notes regarding the differences between this and your attempt:

- You used record syntax for the
`Node`

constructor. It's bad form to use record syntax on sum types, since the functions would then be partial (for example, `pair Leaf`

would be bottom). Since you didn't actually use these and they're not necessary, I removed them.
- You wrapped the key and value in a tuple, with no apparent reason why. I separated them out and placed them directly in the type.
- Your
`closestLess`

function had a return type of `(Integer, v)`

, even though it couldn't always return something of that type. I changed it to `Maybe (Integer, v)`

, so that it can return `Nothing`

instead of having to use `error`

. (Side note: your error message was technically wrong. If you called `closestLess`

where the search value is smaller than all of the nodes, it would fail even though the tree did have elements.)
- Your code is inconsistent as to which is the left and which is the right branch of the nodes. In my code, the left branch is always the one that's on the left in the data constructor.
- You used
`i < fst pair`

and `i == fst pair`

in separate guards. By case-matching on the output of `compare`

instead, you only have to do the comparison once instead of twice.
- You were on the right track with needing a
`precise`

function, but a lot of the logic that you had in `closestLess`

actually needed to be in it.

Here's a quick test case, using the example at the site you linked:

```
Prelude> tree = Node 9 () (Node 4 () (Node 3 () Leaf Leaf) (Node 6 () (Node 5 () Leaf Leaf) (Node 7 () Leaf Leaf))) (Node 17 () Leaf (Node 22 () (Node 20 () Leaf Leaf) Leaf))
Prelude> closestLess 4 tree
Just (4,())
Prelude> closestLess 18 tree
Just (17,())
Prelude> closestLess 12 tree
Just (9,())
Prelude> closestLess 2 tree
Nothing
```

You can also make it lazier (yielding the outer `Just`

as soon as a single candidate is found), at the expense of being a bit more complex:

**import Data.Functor.Identity**
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 :: **Applicative t => t** (Integer, v) -> TreeMap v -> **t** (Integer, v)
precise closestSoFar Leaf = closestSoFar
precise closestSoFar (Node k v l r) = case i `compare` k of
LT -> precise closestSoFar l
EQ -> **pure** (k, v)
GT -> **pure . runIdentity $** precise (**Identity** (k, v)) r

See my question about this for more details about it.

`precise`

function to do. Also, avoid throwing`error`

s in pure functions, instead find a better representation for your result (like using`Maybe`

)`closest lower keys`

so that we can understand what exactly you want your haskell version to do?`min_diff`

and`min_diff_key`

parameters, which - even worse - also have some no-value values like`MAX_INTEGER`

and`-1`

. Write a function`Integer -> TreeMap v -> Maybe (Integer, v) -> Maybe (Integer, v)`

with parameters`searchValue`

,`tree`

, and`closestSoFar`

.