Voici le code que j'ai rencontré quelque part, mais je veux savoir comment cela fonctionne:
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
Sortie: findIndices (== 0) [1,2,0,3,0]
==[2,4]
, où pred
est (==0)
& xs
est[1,2,0,3,0]
Je vais montrer une partie de ma compréhension:
(zip [0..] xs)
Ce que la ligne ci-dessus fait est de mettre des indices à tout dans la liste. Pour l'entrée donnée ci - dessus, il ressemblerait à ceci: [(0,1),(1,2),(2,0),(3,3),(4,0)]
.
(pred . snd)
J'ai trouvé que cela signifie quelque chose comme pred (snd (x))
. Ma question est la suivante: x
la liste est-elle établie à partir de la zip
ligne? Je penche vers oui mais ma supposition est fragile.
Ensuite, est ma compréhension de fst
et snd
. je le sais
fst(1,2) = 1
et
snd(1,2) = 2
Comment ces deux commandes ont-elles un sens dans le code?
Ma compréhension filter
est qu'il renvoie une liste d'articles qui correspondent à une condition. Par exemple,
listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]
donnerait [6,7,8,9,10]
Ma compréhension de la carte est qu'elle applique une fonction à chaque élément de la liste. Par exemple,
times4 :: Int -> Int
times4 x = x * 4
listTimes4 = map times4 [1,2,3,4,5]
donnerait [4,8,12,16,20]
Comment cela fonctionne-t-il globalement? Je pense que j'ai été complet dans ce que je sais jusqu'à présent, mais je ne peux pas tout à fait assembler les morceaux. Quelqu'un peut-il m'aider?
la source
Réponses:
À Haskell, nous aimons dire, suivez les types . En effet les pièces se connectent comme par des fils allant du type au type correspondant:
(premièrement, la composition des fonctions est:
et la règle d'inférence du type de composition de fonction est:
Maintenant, )
donc, dans l'ensemble,
Vous avez demandé, comment ces pièces s'assemblent-elles?
C'est ainsi.
Avec les listes de compréhension , votre fonction s'écrit
qui en pseudocode se lit comme suit:
« liste de résultats contient
i
pour chaque(i,x)
danszip [0..] xs
ce quipred x
tient » .Il le fait en tournant le
n
-longdans
où
[a | True]
est[a]
et[a | False]
est[]
.la source
Eh bien
pred . snd
, ça veut dire\x -> pred (snd x)
. Donc , ce construit essentiellement une fonction qui un élémentx
surpred (snd x)
.Cela signifie donc que l'expression ressemble à:
Voici
x
donc un 2-tuple généré parzip
. Ainsi, afin de savoir si(0, 1)
,(1,2)
,(2, 0)
, etc. sont conservés dans le résultat,snd x
prendra le deuxième élément de ces 2 triplets (donc1
,2
,0
, etc.), et vérifier si lepred
sur tha élément est satisfait ou non. S'il est satisfait, il conservera l'élément, sinon cet élément (le tuple 2) est filtré.Donc, si
(== 0)
c'est lapred
glace, alorsfilter (pred . snd) (zip [0..] xs)
contiendra les 2 tuples[(2, 0), (4, 0)]
.Mais maintenant, le résultat est une liste de 2 tuples. Si nous voulons les indices, nous devons en quelque sorte nous débarrasser du 2-tuple et du deuxième élément de ces 2-tuples. Nous utilisons
fst :: (a, b) -> a
pour cela: cela mappe un 2-tuple sur son premier élément. Donc, pour une liste[(2, 0), (4, 0)]
,map fst [(2, 0), (4, 0)]
reviendra[2, 4]
.la source