Oto kod, który gdzieś natknąłem, ale chcę wiedzieć, jak to działa:
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
Dane wyjściowe: findIndices (== 0) [1,2,0,3,0] == [2,4] , gdzie pred wynosi (== 0), a xs wynosi [1,2,0,3,0]
Pokażę trochę mojego zrozumienia:
(zip [0..] xs)
Powyższa linia wprowadza indeksy do wszystkiego na liście. Dla danych wejściowych podanych powyżej wyglądałoby to tak: [(0,1), (1,2), (2,0), (3,3), (4,0)]
(pred . snd)
Odkryłem, że oznacza to coś w rodzaju pred (snd (x)). Moje pytanie brzmi: czy x jest listą utworzoną z linii zip? Skłaniam się ku tak, ale moje przypuszczenia są wątłe.
Następnie moje rozumienie fst i snd. wiem to
fst(1,2) = 1
i
snd(1,2) = 2
Jak te 2 polecenia mają sens w kodzie?
Rozumiem, że filtr polega na tym, że zwraca listę elementów spełniających warunek. Na przykład,
listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]
dałby [6,7,8,9,10]
Rozumiem, że mapa ma zastosowanie do każdej pozycji na liście. Na przykład,
times4 :: Int -> Int
times4 x = x * 4
listTimes4 = map times4 [1,2,3,4,5]
dałby [4,8,12,16,20]
Jak to ogólnie działa? Wydaje mi się, że byłem wyczerpujący w tym, co wiem do tej pory, ale nie jestem w stanie poskładać całości. Czy ktokolwiek może mi pomóc?