简体   繁体   中英

Manipulating Lists in Haskell using Higher-Order Functions and Lambda Calculus

I am trying to write a very simple function that takes a list (for example : [1,2,3,1,5] ) and returns a list of elements that are directly after a specific element.

What I have reached so far is:

function element list = filter (\x -> element:x) list

My desired output:

function 1 [1,2,3,1,5]

=> [2,5]

Try this

map snd $ filter ((== x) . fst) $ zip theList (tail theList)

This won't work on an empty list, you will still need extra code to deal with that.


How does this work?

First, note that the values flow from right to left. The ($) operator allows this to happen. So, the first part evaluated is the zip function.

zip theList (tail theList)

For your example above, this would yield

zip [1,2,3,1,5] [2,3,1,5]

equaling

[(1,2), (2, 3), (3, 1), (1,5)]

which is the set of concurrent pairs in the list.

Next, the filter is applied

filter ((== x) . fst) $ ....

In English, what this says is, filter out only the concurrent pairs whose first element equals x . The output is

[(1,2), (1,5)]

Now we have the list of concurrent pairs starting with 1 .

Finally, we apply the map

map snd $ ....

This just pulls out the second value of the pair.

map snd [(1,2), (1,5)] = [2,5]

which is the desired value.


Note, my comment above about failing on the empty list.

This is because tail crashes on the empty list

tail [] --error

There are ways to patch this behavior (see the safe package, for instance), but it is mostly bookkeeping at this point, so I left that for you to work out.


Also note that since all of the functions we used are lazy, this approach would work for lists of infinite length as well.

您可以通过简单的列表理解来轻松完成此操作,例如:

successors xs i = [y | (x,y) <- zip xs (drop 1 xs), x == i]

This will work to your specifications

next x (i:y:ys) -- look at the first two items in the list
    | x == i = -- if the first item == x, 
        y : next x (y:ys) -- take the second, and continue minus the first element
    |otherwise = -- not equal, 
        next x (y:ys) -- so skip that element
next _ [_] = [] -- if there's no second element, then stop
next _ _ = [] -- if the list is empty, stop

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM