2

We had to write lambda function in Haskell but it always shows errors. What do I do wrong? all codes have the same kind of error, but I don't understand how to make them right.

length' :: [a] -> [a] -> Int 
length' [] = 0
length' (x:xs) (y:ys) = \n -> if length (x:xs) > (y:ys) then 1 else if (x:xs) == (y:ys) then 0 else if (x:xs) < (y:ys) then -1

find :: a -> [a] -> Bool
find p [] = False
find p xs = \p -> if p `elem` xs then True else False

remove y [] = []
remove y (x:xs) = \xs -> if y == x then xs else x: remove y xs 


• Couldn't match expected type ‘Bool’ with actual type ‘a -> Bool’
• The lambda expression ‘\ p -> ...’ has one argument,
  but its type ‘Bool’ has none
  In the expression: \ p -> if p `elem` xs then True else False
  In an equation for ‘find’:
      find p xs = \ p -> if p `elem` xs then True else False

the errors are the same

Couldn't match expected type ‘[t]’ with actual type ‘[t] -> [t]’
    • The lambda expression ‘\ xs -> ...’ has one argument,
      but its type ‘[t]’ has none
      In the expression: \ xs -> if y == x then xs else x : remove y xs
      In an equation for ‘remove’:
Will Ness
  • 70,110
  • 9
  • 98
  • 181
123
  • 67
  • 5

2 Answers2

11

You have a problem with this function:

find :: a -> [a] -> Bool
find p [] = False
find p xs = \p -> if p `elem` xs then True else False

By its type declaration, it takes a value of the type a, a list of values, also all of the type a, and returns a Bool.

In the find case that matches on p and xs, the compiler must accept the type declaration, so p must be of the type a, and xs must be of the type [a]. This means that the return value must be Bool.

The expression, however, returns a lambda expression. That particular lambda expression has the type Eq a => a -> Bool. You can try that in GHCi:

Prelude> xs = undefined :: [a]
Prelude> :t \p -> if p `elem` xs then True else False
\p -> if p `elem` xs then True else False :: Eq a => a -> Bool

You can fix the problem by not returning a function, i.e. not returning a lambda expression.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
5

Unfortunately there are many mistakes: I'll only point out the first ones.

length' :: [a] -> [a] -> Int 

This states that length' takes two arguments of type [a] and returns an Int. This is weird: why a length function takes two lists? Let's assume two arguments is indeed what you want and move on.

length' [] = 0

Here you define length' having a single argument []. Why not two?

length' (x:xs) (y:ys) = \n -> ...

Here you define length having two arguments, x:xs and y:xs. However, you return a function \n -> ... and that does not match with the Int return type.

Moreover:

length (x:xs) > (y:ys)

above you compare an Int and a list. Is,say, 5 < [1,2,3] true? No, it's a meaningless comparison.

chi
  • 111,837
  • 3
  • 133
  • 218