Este é o código que encontrei em algum lugar, mas quero saber como isso funciona:
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
Saída: findIndices (== 0) [1,2,0,3,0]
==[2,4]
, onde pred
está (==0)
& xs
é[1,2,0,3,0]
Vou mostrar um pouco do meu entendimento:
(zip [0..] xs)
O que a linha acima faz é colocar índices para tudo na lista. Para a entrada dada acima, que seria parecido com este: [(0,1),(1,2),(2,0),(3,3),(4,0)]
.
(pred . snd)
Eu descobri que isso significa algo como pred (snd (x))
. Minha pergunta é: x
a lista é feita a partir da zip
linha? Estou inclinado a sim, mas meu palpite é frágil.
Em seguida, é o meu entendimento de fst
e snd
. Eu sei disso
fst(1,2) = 1
e
snd(1,2) = 2
Como esses dois comandos fazem sentido no código?
Pelo que entendi, filter
ele retorna uma lista de itens que correspondem a uma condição. Por exemplo,
listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]
daria [6,7,8,9,10]
Meu entendimento do mapa é que ele aplica uma função a todos os itens da lista. Por exemplo,
times4 :: Int -> Int
times4 x = x * 4
listTimes4 = map times4 [1,2,3,4,5]
daria [4,8,12,16,20]
Como isso funciona em geral? Eu acho que tenho sido abrangente no que sei até agora, mas não consigo juntar as peças. Alguém pode me ajudar?