How "catch" error e.g., from Set.findIndex

Hello,

The Data.Set function findIndex has the following type signature:

findIndex :: Ord a => a -> Set a -> Int

However, it will throw an error if and when the index can’t be found.

If the index is out of range (less than zero, greater or equal to size of the set), error is called.

What is a common approach to “catching” when this happens?

This way, I can create a function such as:

findIndex :: Text -> FieldValues -> Maybe Int

Thanks to anyone with some guidance here.

Use lookupIndex.

2 Likes

Hello Edmunds,

the function you are looking for is already there!

lookupIndex :: Ord a => a -> Set a -> Maybe Int
1 Like

What a nut! Thank you to both. This is exactly what I needed.

This said, I think the reason I got myopic here was because I have the MonadCatch and MonadThrow as part of my app context. If only to build my skills here, how might I go about using functions that might call error?

If you can avoid getting there (i.e. error), better; as an example think of specific types which enforce some desiderable quality (NonEmpty, etc.). Or simply pattern matching:

case foo of
  []     -> somethingElse
  (a:as) -> a                -- instead of `head a`

If that won’t cut it, catch it!

Lets note that catching pure exceptions can be brittle, an error can be at some intermediate step which is only evaluated late. This means one might need to catch it at every place where we evaluate the thunk. It’s better to either use total (non-partial) functions or be sure that the error case is not triggered because of some invariant that is satisfied.1

3 Likes

Great point. I’m really trying to swim against the current here for no benefit. I think that’s all there is for me to learn here… it makes me wonder why Data.Set has the findIndex in the first place. Thank you.

it makes me wonder why Data.Set has the findIndex in the first place

Many of us wonder the same!

1 Like