开发者

Haskell - Create Set (unique sorted list) - no recursion, no nub

开发者 https://www.devze.com 2023-01-18 02:34 出处:网络
is it Possible to create a function that will create a set with an input of a list. I just can\'t think of any way without using recursion.

is it Possible to create a function that will create a set with an input of a list.

I just can't think of any way without using recursion.

I can use high order functions like fold, filter, map, zip. I just can't have recursion in my function.

Obviously I can't use nub.

I've been banging my head trying to figure out how to get rid of duplicates without recursion o开发者_开发问答r any type of loop (at least I don't think we can use loops, gonna ask).


One way to do it:

  1. Sort the list.
  2. Zip the list with its tail (turning e.g. [1,1,2,3] into [(1,1),(1,2),(2,3)])
  3. Remove all the pairs where both items are the same.
  4. Return the list containing the first element of the sorted list followed by the second item of each pair in the zipped list.

In code:

import Data.List

setify [] = []
setify xs = x : map snd (filter (uncurry (/=)) (zip sxs (tail sxs)))
    where sxs = sort xs
          x   = head sxs


Another would be to use a fold to accumulate the values along with a membership check if it has been seen before.

setify :: (Eq b) => [b] -> [b]
setify = foldl f []
where f acc next | next `elem` acc = acc 
                 | otherwise       = next:acc

Not the fastest method, but it get the job done.


Are you allowed to use group method? If so, then you can sort the list, group them, and finally take 1 item from each group.

import Data.List

setify :: Eq a => [a] -> [a]
setify = map head . group . sort


Why all the complicated (and wrong!) solutions? Just do this:

uniq [] = []
uniq (x:xs)= x:(uniq (filter (/=x) xs))

setify xs = uniq $ sort xs -- If you want to sort too.

It filters each element from the tail of the list. Simple.

0

精彩评论

暂无评论...
验证码 换一张
取 消