Este es el código que encontré en alguna parte, pero quiero saber cómo funciona esto:
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
Salida: findIndices (== 0) [1,2,0,3,0]==[2,4] , donde predes (==0)y xses[1,2,0,3,0]
Mostraré algo de mi comprensión:
(zip [0..] xs)
Lo que hace la línea anterior es poner índices a todo en la lista. Para la entrada dada anteriormente, sería el siguiente: [(0,1),(1,2),(2,0),(3,3),(4,0)].
(pred . snd)
Descubrí que esto significa algo así pred (snd (x)). Mi pregunta es, ¿ xla lista está hecha desde la ziplínea? Me estoy inclinando hacia sí, pero mi suposición es débil.
A continuación, es mi comprensión de fsty snd. Yo sé eso
fst(1,2) = 1
y
snd(1,2) = 2
¿Cómo tienen sentido estos dos comandos en el código?
Entiendo filterque devuelve una lista de elementos que coinciden con una condición. Por ejemplo,
listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]
daría [6,7,8,9,10]
Según tengo entendido, map aplica una función a cada elemento de la lista. Por ejemplo,
times4 :: Int -> Int
times4 x = x * 4
listTimes4 = map times4 [1,2,3,4,5]
daría [4,8,12,16,20]
¿Cómo funciona esto en general? Creo que he sido comprensivo en lo que sé hasta ahora, pero no puedo armar las piezas. ¿Alguien puede ayudarme?
fuente

Respuestas:
En Haskell nos gusta decir, sigue los tipos . De hecho, las piezas se conectan como si fueran cables que van del tipo al tipo correspondiente:
(primero, la composición de la función es:
y la regla de inferencia de tipo de composición de función es:
Ahora, )
entonces, en general,
Usted ha preguntado, ¿cómo encajan estas piezas?
Así es como.
Con las comprensiones de listas , su función se escribe como
que en pseudocódigo lee:
msgstr "la lista de resultados contiene
ipara cada uno(i,x)de formazip [0..] xsque sepred xmantenga" .Lo hace girando el
nlargodentro
donde
[a | True]es[a]y[a | False]es[].fuente
Bueno
pred . snd, significa\x -> pred (snd x). Así que esto básicamente construye una función que mapea un elementoxdepred (snd x).Esto significa que la expresión se ve así:
Aquí
xhay una tupla 2 generada porzip. Así que con el fin de saber si(0, 1),(1,2),(2, 0), etc., están retenidos en el resultado,snd xse llevará el segundo elemento de estas 2-tuplas (así1,2,0, etc.), y comprobar si elpredTha elemento se cumple o no. Si está satisfecho, retendrá el elemento; de lo contrario, ese elemento (la tupla 2) se filtrará.Entonces, si
(== 0)es elpredicate,filter (pred . snd) (zip [0..] xs)contendrá las 2 tuplas[(2, 0), (4, 0)].Pero ahora el resultado es una lista de 2-tuplas. Si queremos los índices, de alguna manera necesitamos deshacernos de las 2 tuplas y el segundo elemento de estas 2 tuplas. Usamos
fst :: (a, b) -> apara eso: esto asigna una tupla de 2 en su primer elemento. Entonces, para una lista[(2, 0), (4, 0)],map fst [(2, 0), (4, 0)]volveremos[2, 4].fuente