Reputation: 326
I have a list of Strings I want to filter through. My predicate is that the string should begin with an uppercase letter.
eg. when I run onlyLowercase ["boy", "girl", "Hi"]
it should give me a list of ["boy", "girl"]
I can do it using pattern matching and guards, but I'm using the learnyouahaskell (http://learnyouahaskell.com) book and I came across the topic on higher-order functions. I read about the filter function and thought it could achieve what I want to do in far fewer lines of code.
Using pattern Matching/Guards (This works well and solves my problem)
onlyLowercase :: [[Char]] -> [[Char]]
onlyLowercase [] = []
onlyLowercase (x:xs)
| isLower (head x) = x : onlyLowercase xs
| otherwise = onlyLowercase xs
Using the filter function
onlyLowercase2 :: [String] -> [String]
onlyLowercase2 [] = []
onlyLowercase2 (x:xs) = filter isLower x : onlyLowercase2 xs
Unfortunately, when I run onlyLowercase2 ["boy", "girl", "Hi"]
,
I get a list of ["boy", "girl", "i"]
.
I want to know if there's a way I can filter my list of strings using the first character in my string (without creating any auxiliary function that could check the String and return true if the first letter is lowercase).
I also tried using
onlyLowercase2 (x:xs) = filter (isLower head x) : onlyLowercase2 xs
but that didn't even compile. Basically, I'm just trying to figure out how the filter function can be used on a list of lists. Thank you, in advance, for any assistance rendered.
Upvotes: 2
Views: 2642
Reputation: 1315
Using Data.List
and Data.Char
:
import Data.List
import Data.Char
onlyLowerCase :: [String] -> [String]
onlyLowerCase = filter (all isLower)
I use the all
function which checks that all
elements of a list satisfy a predicate. In this case all isLower
will return true if all letters in a String
are lowercase. Then just filter
the Strings
that are all lowercase. The Haskell Report has a good reference for List
and Char
functions among other useful libraries.
Upvotes: 1
Reputation: 326
Thanks to Willem Van Onsem's suggestion to use a lambda expression as a filter function, I read further and came up with this 2 line solution.
onlyLowercase2 :: [String] -> [String]
onlyLowercase2 = filter (\st-> ("" /= st) && (isLower $ head st))
Not sure if it's perfect, but at least it's working.
Upvotes: 5