0

I made this code where I need to find elements in a list that appears only once for example: for input [1,2,2,3,4,4], the output will be: [1,3]

unique ::      =[a]->[a]
unique xs      =[x|x<-xs, elemNum x xs ==1]

elemNum ::      Int -> [Int]->[Int]
elemNum x  (y:ys)   
              | x==y         =1+ elemNum x ys
              | otherwise  =elemNum x ys

However I am getting an error : Not in scope: `unique'

Is this the correct way to use 2 function in Haskell? (define them at the same file), What'a wrong with the code?

2
  • 4
    I get a parse error on the = in the first line. After fixing that, I get type errors. Because you only mention a 'not in scope' error, it sounds like you're trying to use unique in another file or in ghci without loading/importing the definitions (so they don't get parsed/type checked). Commented May 3, 2014 at 13:59
  • I just saved this file under the name unique.hs, then I loaded it, and then I run the query unique [1,1,2,3]. Commented May 3, 2014 at 14:17

3 Answers 3

2

There are a few problems in your code:

  1. type signature of unique is wrong, it should be

    unique :: (Eq a) => [a] -> [a]

    that type constraint (Eq a) comes from elemNum

  2. type signature of elemNum also wrong, it should be

    elemNum :: (Eq a) => a -> [a] -> Int

    that type constraint comes from ==, and the type of its first parameter no need to be Int, but its return type should be Int because you want to find out how many x in xs.

    Also, you forgot to deal with empty list in that definition.

Here is a fixed version of your code:

unique :: (Eq a) => [a] -> [a]
unique xs      =[x| x<-xs, elemNum x xs == 1]

elemNum :: (Eq a) => a -> [a] -> Int
elemNum x [] = 0
elemNum x  (y:ys)   
              | x==y       = 1 + elemNum x ys
              | otherwise  = elemNum x ys

Here is another implementation:

onlyOnce [] = []
onlyOnce (x:xs)
    | x `elem` xs = onlyOnce $ filter (/=x) xs
    | otherwise = x : onlyOnce xs

If x occurs in xs, then the result of onlyOnce (x:xs) should be the same as the result of applying onlyOnce to the result of removing all occurrences of x from xs; otherwise, x occurs in (x:xs) only once, so x should be part of the final result.

Sign up to request clarification or add additional context in comments.

Comments

1

You have an equals sign in the Type declaration for unique:

unique ::      =[a]->[a]    

should be

unique :: [a] -> [a]

Comments

1

In my opinion it is much easier to implement this function using functions from Data.List module:

import Data.List
unique :: (Ord a) => [a] -> [a]
unique = map (\(y,_) -> y) . filter (\(x,l) -> l == 1) . map (\l@(x:xs) -> (x,length l)) . group . sort

1 Comment

(\(y,_) -> y) is fst. (\(x,l) -> l == 1) is ((==1).snd). you could shorten the definition to just concat . filter ((==1).length) . group . sort, or f xs = [x | [x] <- group $ sort xs]. But any solution with sort will potentially change the order of elements.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.