views:

147

answers:

2

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 or any type of loop (at least i don't think we can use loops, gonna ask).

+4  A: 

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
sepp2k
would have never thought of that.
Matt
You probably shouldn't give the code, just the method, since this is homework...
mathepic
It doesn't work, though! Think about/try out what happens when the first element of the list is the largest...
yatima2975
@yatima: Ah, shoot. My instructions were correct, but my code is wrong because I took the first element of the original list instead of the first element of the sorted list.
sepp2k
+2  A: 

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.

sabauma