簡體   English   中英

結合 Haskell 代碼的片段以獲得更大的圖景

[英]Combining fragments of Haskell Code to get the bigger picture

這是我在某個地方遇到的代碼,但想知道它是如何工作的:

    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] ,其中pred(==0) & xs[1,2,0,3,0]

我將展示我的一些理解:

    (zip [0..] xs)

上面這行所做的是將索引放入列表中的所有內容。 對於上面給出的輸入,它看起來像這樣: [(0,1),(1,2),(2,0),(3,3),(4,0)]

    (pred . snd)

我發現這意味着類似pred (snd (x)) 我的問題是, x是由zip線組成的列表嗎? 我傾向於是的,但我的猜測是站不住腳的。

接下來是我對fstsnd的理解。 我知道

    fst(1,2) = 1 

    snd(1,2) = 2

這兩個命令在代碼中如何有意義?

我對filter的理解是它返回一個匹配條件的項目列表。 例如,

    listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]

會給[6,7,8,9,10]

我對 map 的理解是,它將 function 應用於列表中的每個項目。 例如,

    times4 :: Int -> Int
    times4 x = x * 4
    listTimes4 = map times4 [1,2,3,4,5]

會給[4,8,12,16,20]

這總體上如何運作? 我想我到目前為止所知道的已經很全面了,但不能把這些部分放在一起。 有人可以幫幫我嗎?

我發現這意味着類似pred (snd (x)) 我的問題是,x 是由 zip 線組成的列表嗎? 我傾向於是的,但我的猜測是站不住腳的。

pred. snd pred. snd ,表示\x -> pred (snd x) 所以這基本上構造了一個 function ,它將元素x映射到pred (snd x)

因此,這意味着表達式看起來像:

filter (\x -> pred (snd x)) (zip [0..] xs)

因此,這里x是由zip生成的 2 元組。 所以為了知道(0, 1) , (1,2) , (2, 0)等是否保留在結果中, snd x將取這些 2 元組的第二個元素(所以1 , 2 , 0等),並檢查是否滿足 tha 元素的pred 如果滿足,它將保留該元素,否則該元素(2元組)將被過濾掉。

因此,如果(== 0)是謂詞,則 filter ( pred filter (pred. snd) (zip [0..] xs)將包含 2 元組[(2, 0), (4, 0)]

但現在結果是一個 2 元組列表。 如果我們想要索引,我們需要以某種方式擺脫 2 元組以及這些 2 元組的第二個元素。 我們為此使用fst:: (a, b) -> a :這將 2 元組映射到其第一個元素。 因此,對於列表[(2, 0), (4, 0)]map fst [(2, 0), (4, 0)]將返回[2, 4]

在 Haskell 我們想說,遵循 types 實際上,這些部分就像通過從類型到相應類型的電線連接一樣:

(一、 function組成為:

   (f >>> g) x  =  (g . f) x  =        g (f x)
   (f >>> g)    =  (g . f)    =  \x -> g (f x)

function組合類型推斷規則為:

    f        :: a -> b                   --      x  :: a
          g  ::      b -> c              --    f x  :: b
   -------------------------             -- g (f x) :: c
    f >>> g  :: a ->      c
    g  .  f  :: a ->      c

現在, )

findIndices :: (b -> Bool) -> [b] -> [Int]
findIndices pred  = \xs -> map fst ( filter (pred . snd) ( zip [0..] xs ))
                  =        map fst . filter (pred . snd) . zip [0..]
                  =  zip [0..]  >>>  filter (snd >>> pred)  >>>  map fst
---------------------------------------------------------------------------
zip :: [a] ->          [b]        ->        [(a,  b)]
zip  [0..] ::          [b]        ->        [(Int,b)]
---------------------------------------------------------------------------
        snd           :: (a,b) -> b
                pred  ::          b -> Bool
       ------------------------------------
       (snd >>> pred) :: (a,b)      -> Bool
---------------------------------------------------------------------------
filter ::               (t          -> Bool) -> [t]   -> [t]
filter (snd >>> pred) ::                      [(a,b)] -> [(a,b)]
filter (snd >>> pred) ::                    [(Int,b)] -> [(Int,b)]
---------------------------------------------------------------------------
    fst ::                                   (a,   b) -> a
map     ::                                  (t        -> s) -> [t] -> [s]
map fst ::                                                 [(a,b)] -> [a]
map fst ::                                               [(Int,b)] -> [Int]

所以,總的來說,

zip  [0..] ::          [b]        ->        [(Int,b)]
filter (snd >>> pred) ::                    [(Int,b)] -> [(Int,b)]
map fst ::                                               [(Int,b)] -> [Int]
---------------------------------------------------------------------------
findIndices pred ::    [b] ->                                         [Int]

你問過,這些部分是如何組合在一起的?

就是這樣。


使用列表推導,您的 function 寫為

findIndices pred xs = [ i | (i,x) <- zip [0..] xs, pred x ]

在偽代碼中顯示:

“結果列表包含zip [0..] xs中每個 ( i (i,x)的 i,這樣pred x成立”

它通過轉動n -long 來做到這一點

xs = [a,b,...,z] = [a] ++ [b] ++ ... ++ [z]

進入

  [0 | pred a] ++ [1 | pred b] ++ ... ++ [n-1 | pred z]

其中[a | True] [a | True][a][a | False] [a | False][]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM