How can i remove special characters from string and lowercase it and return it as list in Haskell
for example a sample string :
"I'm 25, working in Switzerland;;"
and get output like
['i','m','working','in','switzerland']
How can i remove special characters from string and lowercase it and return it as list in Haskell
for example a sample string :
"I'm 25, working in Switzerland;;"
and get output like
['i','m','working','in','switzerland']
First off, change your question. It currently reads as though you've been assigned homework and you want to take the shortest route to a grade. I would suggest wording it as "How do I approach simple problem solving in Haskell?" Then give your question as an exemplar of a problem that could be solved. The alternative is to take a hit to your reputation, remembering that even if you delete this question the bad reputation will still haunt you.
Two things need to happen to that string.
This merits the mention of a fundemental rule of any question answering scenario. Read the question, read the question, read the bloody question!
Looks pretty easy, doesn't it? Of course I am being a little disingenuous, because I selected those two things, and in that order, because I know it'll be easier that way. That's plain old knowledge of Haskell.
How do we search for a solution to number 1?
Do it by first principles? No, not on a common problem like this. Sure, if you have some weird custom type and data structure, you'd be forced to. Though you would, if you chose your types carefully, have access to abstractions like Semigroup, Monoid, Functor, Applicative, etc., to make that job easier.
Google or SOF search? ¡Sí, Sí, Señor! This is a good bet. Find someone who has already done the problem. Don't be an idiot! Of course look for an easy way first if it looks like an option. In this case, yes, there is an answer, and it's close at hand. SOF: Converting lowercase to uppercase. Not an exact match, but it does not take a lot of imagination to change toUpper
into toLower
.
# Give a monkey a fish...
import Data.Char (toLower)
uncapitalize = map toLower
Hoogle it? This is a good solution, but you need to have a good grasp of type signatures (essential if you're working with Haskell) to use it effectively. I got the solution real fast by searching at hoogle with the following:
Char -> Char
NOT char -> char
. The first is a type signature of a function that takes a concrete type Char and returns a concrete type Char. The second is the type signature of a function that take ANY type and returns that same type. The first is very specific, the second VERY general. Anyway, you've followed the link by now and you see that the function you were looking for was the first result. Amazing!
toLower :: Char -> Char
Along with the module it is imported from. Noice! But still not as helpful as the SOF answer, since that scaffolds everything for a newbie.
We're not done on this one yet. Just because two sources say that a thing is possible, doesn't mean that you can do it. Jump out to ghci
to do some testing. Hopefully with stack ghci
. Then from the ghci prompt >
toLower 'A'
will give you 'a'
. Where 'A' :: Char
. Good. Now to get toLower
to work on a list. List brings to mind map
immediately, but don't take my word for it. From ghci
, try :t map
and :t toLower
to check their types and how you can chuck them together. You'll probably need to import Data.Char
with import Data.Char
. Now we're ready to do some chucking and shoving1:
map toLower "AnyThing"
and it may or may not fail depending on if you have :set -XOverloadedStrings
in ghci. To be sure, be explicit:
map toLower ("I'm 25, working in Switzerland;;" :: [Char])
and out pops "i'm 25, working in switzerland;;"
. We're halfway done. By the way, ghci
is a common way of working through problems in haskell. Shoving things together like a monkey is how we are wired. Embrace it. Indeed, why think when you can shove away in a consequence free environment? It's a no-brainer.
How do we search for a solution to number 2? This is a tougher problem, but using the same search options we used above.
Do it by first principles? Yes, probably. Though lets search Google and SOF first.
Luckily, it's a problem others have considered before. We get a general solution for free.
wordsWhen :: (Char -> Bool) -> String -> [String]
wordsWhen p s = case dropWhile p s of
"" -> []
s' -> w : wordsWhen p s''
where (w, s'') = break p s'
This is a general solution to our problem. It takes a predicate (hence the p
) function (Char -> Bool)
and drops anything that matches it, and saves the rest. break
works by breaking any chunk of Char
s that do not match the predicate into w
of the tuple (w, s'')
.
Note on convention: the apostrophe superscript in s'
refers to s'
being somehow derivative of, or coming from s
.
The function wordsWhen
calls itself recursively on whatever remains of the string i.e. s''
, until it is empty (the first case match).
How do we test this in ghci
?
I'm glad you asked. To enter a multi-line definition directly into ghci
use this bracketing, :{
begins the code block, and :}
ends it. Or use :set +m
. Both of which are outlined here.
Since the predicate chooses which characters to drop, the logical choice is for it to be (not . isLower)
. You should have encountered isLower
when rooting around in Date.Char
. The not
is logical negation, and the .
is function composition.
Therefore:
wordsWhen (not . isLower) "i'm 25, working in switzerland;;"
solves the second part. Resolving these two into a solution is a job for any monkey who can shove things together using ghci
.
[1]: Absolutely no one's formal definition of this activity.
I will not answer your question entirely, but I will give you some pointers using hoogle:
Char -> Bool
that can help. Possibly isAlphaNum
?Char -> Char
that can help.Char
s to an entire String
? Maybe there's a function of type (Char -> Char) -> String -> String
. Maybe there's a more general function that can help us?break :: (a -> Bool) -> [a] -> ([a], [a])
for free.Now, given these functions, you can build the complete function you're looking for, by using recursion. Good luck!