Home > Back-end >  Couldn't match expected type ‘Bool’ with actual type ‘Char -> Bool´
Couldn't match expected type ‘Bool’ with actual type ‘Char -> Bool´

Time:10-20

Hi I'm trying to filter a string so it only outputs the letters in it.

This is what I have so far

filteredText :: String -> String
filteredText (x:xs) = filter (\toLower x -> x `elem` ['a'..'z']) xs

and gives me this error:

Couldn't match expected type ‘Bool’
with actual type ‘Char -> Bool’

CodePudding user response:

I believe what you want is filteredText xs = filter (\x -> (toLower x) `elem` ['a'..'z']).

Between \ and -> are the formal arguments to anonymous functions. You had \toLower x ->..., meaning two arguments where one is expected:

filter :: (a -> Bool) -> [a] -> [a] -- takes f :: (a -> Bool), as :: [a], gives [a]

f only takes one argument.

Also, filteredText (x:xs) pattern matches x as the head of the list (the first element) and xs the tail (the rest of the list but the head). Therefore, the first element was being ignored. I assumed it was no intentional.

CodePudding user response:

The first parameter of filter should be a function that when called for an element determine whether we wish to keep that element in the result or not. This is thus a function that for a given x will return True or False, and thus has as shape \x -> ….

Another problem is that you match on the (x:xs) pattern. This means that your expression would omit the first item of the list, and only will process the tail of the list. Furthermore this means that passing an empty string, would raise an error. The entire list can thus be named xs:

filteredText :: String -> String
filteredText xs = filter (\x -> …) xs

Here you thus need to implement the expression: you first use toLower to obtain the lowercase variant of the given character, and then you can use `elem` ['a' .. 'z'] to check if the the lowercase of x belongs to that list. I leave the implementation as an exercise.

CodePudding user response:

You can get something very close to what you wrote, with

> filter ( \ (toLower -> x) -> x `elem` ['a'..'z'] ) "1243sdfwerweKJHKJ(*&@*#9798"
=> "sdfwerweKJHKJ"

You will need to enable ViewPatterns for that. The GHCi command is :set -XViewPatterns.

  • Related