在 Haskell 中捕获空列表异常(head)

Catch empty list exeption in Haskell (head)

我正在编写一个函数,用于从列表中获取第一个偶数的索引。我得到的列表可能包含也可能不包含偶数,如果列表中没有偶数,我想 return -1。列表可以是无限的。

这是我写的

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

我可以这样做:

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

但是如您所见,这并不是最有效的方法。列表 [1..100000] 包含很多偶数,我只需要第一个。我需要 Haskell 的懒惰,所以我需要在那里请求 head,但是当列表为空时 head 抛出一个空列表异常(即列表中没有偶数)。我找不到 Haskell 等同于 Python 的 try: ... except: ...。我能找到的关于异常的所有信息都与 IO 相关。我需要的是 except Prelude.head = -1 或类似的东西。

Haskell 是惰性的,所以 evens 不会 被完全评估。有问题的部分是不需要的 length evens 。您可以使用 null :: Foldable f => f a -> Bool 模式匹配 检查。例如:

import Data.List(<strong>findIndex</strong>)

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

对于 findIndex :: (a -> Bool) -> [a] -> Maybe Int,您不需要考虑空列表,因为它已经考虑了这一点。

或者我们可以 return -1 如果没有这样的项目:

import Data.List(<strong>findIndex</strong>)
import Data.Maybe(fromMaybe)

posicPrimerPar' :: [Int] -> Int
posicPrimerPar' = <strong>fromMaybe (-1)</strong> . findIndex even