简体   繁体   中英

Can someone explain this simple Haskell code to me in detail

I found this on a really old post and did not want to ask there because it might never get answered.

f xs = maximum . filter (< maximum xs) $ xs

It looks to me like it is

  • taking the maximum of a filtered list
  • that is less than the maximum of the list

secondLargest :: (Num a, Ord a) => [a] -> a
secondLargest [] = error "Empty List"
secondLargest [x] = error "Empty List"
secondLargest xs
    | ((maximum . filter (< maximum xs) $ xs) >= (maximum xs)) = maximum xs
    | otherwise = (maximum . filter (< maximum xs) $ xs)

the code above is what I am working with now. Basically I am unable to sort the list and the code above finds the second largest element as long as the largest and the second largest are not the same.

would anyone be able to help shed some light?

It's really simple:

f xs = maximum . filter (< maximum xs) $ xs

Let's suppose xs = [1,2,3,4,5] . Hence, maximum xs = 5 . Thus, we have:

f [1,2,3,4,5] = maximum . filter (< 5) $ [1,2,3,4,5]

Next, we filter out all the elements less than 5 . Hence we get:

f [1,2,3,4,5] = maximum $ [1,2,3,4] -- notice that 5 is no more in the list

Finally, we get the maximum of the remaining elements:

f [1,2,3,4,5] = 4

This happens to be the second largest element of the original list.

If you want to account for duplicates as you've asked in the comments, you can use Data.List.delete instead of filter to remove the largest element. This will only remove a single instance of it:

import Data.List (delete)

f xs = maximum . delete (maximum xs) $ xs

This yields:

λ. f [1,2,3,4,5]
4
λ. f [1,2,3,4,5,5]
5

Of course, this only works for lists of length 2 or longer. If you want to account for all cases so the function is total, you can do something like this:

f xs | length xs >= 2 = maximum . delete (maximum xs) $ xs
     | null xs        = 0   -- default case when the list is empty
     | otherwise      = maximum xs

To do it without the import, you can implement delete by hand:

delete :: Eq a => a -> [a] -> [a]
delete x [] = []
delete x (y:ys) | x == y    = ys
                | otherwise = y : delete x ys

It finds the second largest number from a array xs , to break it down.

let xs = [1, 2, 3, 4]
let a = filter (< maximum xs) xs
-- a is an array of all elements from 'xs' except of the max elem of 'xs'
-- which is [1, 2, 3]

let b = maximum (a) -- gets the largest elem of a
--  b is th largest element of 'a'
-- which is 3

and applying maximum on that gives the second largest elem .

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