Ohad
Ohad

Reputation: 1631

Using few functions in Haskell together

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?

Upvotes: 0

Views: 172

Answers (3)

Lee Duhem
Lee Duhem

Reputation: 15121

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.

Upvotes: 2

Yevgeniy.Chernobrivets
Yevgeniy.Chernobrivets

Reputation: 3194

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

Upvotes: 1

creichert
creichert

Reputation: 536

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

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

should be

unique :: [a] -> [a]

Upvotes: 1

Related Questions