Ini adalah kode yang saya temukan di suatu tempat tetapi ingin tahu cara kerjanya:
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
Output: findIndices (== 0) [1,2,0,3,0]
==[2,4]
, di mana pred
adalah (==0)
& xs
adalah[1,2,0,3,0]
Saya akan menunjukkan beberapa pemahaman saya:
(zip [0..] xs)
Apa yang dilakukan oleh baris di atas adalah meletakkan indeks pada semua yang ada dalam daftar. Untuk input yang diberikan di atas, akan terlihat seperti ini: [(0,1),(1,2),(2,0),(3,3),(4,0)]
.
(pred . snd)
Saya menemukan bahwa ini berarti sesuatu seperti pred (snd (x))
. Pertanyaan saya adalah, apakah x
daftar dibuat dari zip
garis? Saya condong ke arah ya tapi dugaan saya lemah.
Selanjutnya, adalah pemahaman saya tentang fst
dan snd
. saya tahu itu
fst(1,2) = 1
dan
snd(1,2) = 2
Bagaimana kedua perintah ini masuk akal dalam kode?
Pemahaman saya filter
adalah bahwa ia mengembalikan daftar item yang cocok dengan suatu kondisi. Contohnya,
listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]
akan memberi [6,7,8,9,10]
Pemahaman saya tentang peta adalah bahwa ia menerapkan fungsi untuk setiap item dalam daftar. Contohnya,
times4 :: Int -> Int
times4 x = x * 4
listTimes4 = map times4 [1,2,3,4,5]
akan memberi [4,8,12,16,20]
Bagaimana cara kerjanya secara keseluruhan? Saya pikir saya telah komprehensif dalam apa yang saya ketahui sejauh ini tetapi tidak bisa menyatukan potongan-potongan itu. Adakah yang bisa membantu saya?
sumber
Jawaban:
Di Haskell kami ingin mengatakan, ikuti tipenya . Memang potongan-potongan terhubung seolah-olah dengan kabel dari jenis ke jenis yang sesuai:
(pertama, komposisi fungsi adalah:
dan aturan inferensi tipe komposisi fungsi adalah:
Sekarang, )
jadi, secara keseluruhan,
Anda sudah bertanya, bagaimana potongan-potongan ini cocok?
Begini caranya.
Dengan pemahaman daftar , fungsi Anda ditulis sebagai
yang dalam pseudocode berbunyi:
+ msgstr "daftar hasil berisi
i
untuk masing - masing(i,x)
dalamzip [0..] xs
yangpred x
menyimpan" .Ini melakukan ini dengan memutar-
n
panjangke
di mana
[a | True]
adalah[a]
dan[a | False]
adalah[]
.sumber
Ya
pred . snd
berarti\x -> pred (snd x)
. Jadi ini pada dasarnya membangun sebuah fungsi yang memetakan elemenx
padapred (snd x)
.Ini dengan demikian berarti bahwa ekspresi itu terlihat seperti:
Ini
x
adalah 2-tuple yang dihasilkan olehzip
. Jadi untuk mengetahui apakah(0, 1)
,(1,2)
,(2, 0)
, dll dipertahankan dalam hasil,snd x
akan mengambil elemen kedua ini 2-tupel (jadi1
,2
,0
, dll), dan memeriksa apakahpred
pada elemen tha puas atau tidak. Jika puas, itu akan mempertahankan elemen, jika elemen itu (2-tuple) disaring.Jadi jika
(== 0)
adalahpred
icate, makafilter (pred . snd) (zip [0..] xs)
akan berisi 2-tupel[(2, 0), (4, 0)]
.Tetapi sekarang hasilnya adalah daftar 2-tupel. Jika kita menginginkan indeks, kita harus menyingkirkan 2-tuple, dan elemen kedua dari 2-tupel ini. Kami menggunakan
fst :: (a, b) -> a
untuk itu: ini memetakan 2-tuple pada elemen pertama. Jadi untuk daftar[(2, 0), (4, 0)]
,map fst [(2, 0), (4, 0)]
akan kembali[2, 4]
.sumber