Эта функция уже присутствует в библиотеке (elemIndex
), но давайте все равно ее реализуем.
Учитывая xs = [x0,x1,...]
, мы имеем zip xs [0..] = [(x0,0),(x1,1),...]
.Затем мы можем найти в последнем списке пару, удовлетворяющую предикату \(x,_) -> x==n
.
import Data.List
indexOf :: (Eq a) => a -> [a] -> Maybe Int
indexOf n xs = fmap snd . find (\(x,_) -> x==n) $ zip xs [0..]
Выше, zip
добавляет индексы, find
вернет Just (n,index)
в случае успеха и fmap snd
преобразует это в Just index
.
Обратите внимание, что мы предпочитаем возвращать Nothing
вместо -1
, что не является идиоматическим в Haskell, где мы предпочитаем использовать Maybe
вместо
Наконец, обратите внимание, что приведенный выше код не является неэффективным: благодаря лени, zip
будет добавлять индексы только к тем элементам, которые требуются find
, поэтому он не будет сканировать весь список, если нужный элемент не найден..
В качестве упражнения может потребоваться кодировать fmap snd . find (\(x,_) -> x==n)
с явной рекурсией.