Home > Blockchain >  Catch empty list exeption in Haskell (head)
Catch empty list exeption in Haskell (head)

Time:03-25

I'm writing a function that gets the index of the first even number from a list. The list I get may or may not contain even numbers, and I'd like to return -1 if there are no even numbers in the list. The list can be infinite.

I wrote this

posicPrimerPar'' :: [Int] -> Int
posicPrimerPar'' a = fromJust (elemIndex (head (filter (even) a)) a)

I could do something like:

posicPrimerPar' :: [Int] -> Int
posicPrimerPar' a = case length evens of
  0 -> -1;
  n -> fromJust elemIndex (head evens) a
  where evens = filter (even) a

But as you can see, this is not the most efficient way of doing it. A list [1..100000] contains a lot of even numbers, and I just need the first one. I need Haskell's laziness, so I need to ask for the head right there, but head throws an empty list exception when the list is empty (i.e. there are no even numbers in the list). I cannot find the Haskell equivalent of Python's try: ... except: .... All I could find regarding exceptions were IO related. What I need is except Prelude.head = -1 or something like that.

CodePudding user response:

Haskell is lazy, so evens will not be fully evaluated. The problematic part is the length evens which is not necessary. You can check with null :: Foldable f => f a -> Bool, or with pattern matching. For example:

import Data.List(findIndex)

posicPrimerPar' :: [Int] -> Maybe Int
posicPrimerPar' [] = Nothing
posicPrimerPar' xs = findIndex even xs

for findIndex :: (a -> Bool) -> [a] -> Maybe Int, you however do not need to take into account the empty list, since it already considers this.

or we can return -1 in case there is no such item:

import Data.List(findIndex)
import Data.Maybe(fromMaybe)

posicPrimerPar' :: [Int] -> Int
posicPrimerPar' = fromMaybe (-1) . findIndex even
  • Related