Haskell - Removing non-letter characters but ignoring white spaces?












3















I am very new to Haskell. I am trying to return a list of strings from a given string (which could contain non-letter characters) but I get a single string in the list.



The below code shows What I have tried so far:



toLowerStr xs = map toLower xs

--drop non-letters characters
dropNonLetters xs = words $ (filter (x -> x `elem` ['a'..'z'])) $ toLowerStr xs



  • lowercase all the characters by using toLower function

  • remove non-letter characters by using filter function

  • return a list of strings by using words function


I think the filter function is removing the white spaces and therefore it becomes a single string. I tried using isSpace function but I don't know exactly how to implement it in this case.



What is it that I am doing wrong? I get this output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orangeappleapple"]


But I want to achieve the below output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]









share|improve this question

























  • What with tabs, ..

    – Willem Van Onsem
    Dec 21 '17 at 13:58











  • @WillemVanOnsem spaces between words

    – Big Smile
    Dec 21 '17 at 13:58


















3















I am very new to Haskell. I am trying to return a list of strings from a given string (which could contain non-letter characters) but I get a single string in the list.



The below code shows What I have tried so far:



toLowerStr xs = map toLower xs

--drop non-letters characters
dropNonLetters xs = words $ (filter (x -> x `elem` ['a'..'z'])) $ toLowerStr xs



  • lowercase all the characters by using toLower function

  • remove non-letter characters by using filter function

  • return a list of strings by using words function


I think the filter function is removing the white spaces and therefore it becomes a single string. I tried using isSpace function but I don't know exactly how to implement it in this case.



What is it that I am doing wrong? I get this output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orangeappleapple"]


But I want to achieve the below output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]









share|improve this question

























  • What with tabs, ..

    – Willem Van Onsem
    Dec 21 '17 at 13:58











  • @WillemVanOnsem spaces between words

    – Big Smile
    Dec 21 '17 at 13:58
















3












3








3








I am very new to Haskell. I am trying to return a list of strings from a given string (which could contain non-letter characters) but I get a single string in the list.



The below code shows What I have tried so far:



toLowerStr xs = map toLower xs

--drop non-letters characters
dropNonLetters xs = words $ (filter (x -> x `elem` ['a'..'z'])) $ toLowerStr xs



  • lowercase all the characters by using toLower function

  • remove non-letter characters by using filter function

  • return a list of strings by using words function


I think the filter function is removing the white spaces and therefore it becomes a single string. I tried using isSpace function but I don't know exactly how to implement it in this case.



What is it that I am doing wrong? I get this output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orangeappleapple"]


But I want to achieve the below output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]









share|improve this question
















I am very new to Haskell. I am trying to return a list of strings from a given string (which could contain non-letter characters) but I get a single string in the list.



The below code shows What I have tried so far:



toLowerStr xs = map toLower xs

--drop non-letters characters
dropNonLetters xs = words $ (filter (x -> x `elem` ['a'..'z'])) $ toLowerStr xs



  • lowercase all the characters by using toLower function

  • remove non-letter characters by using filter function

  • return a list of strings by using words function


I think the filter function is removing the white spaces and therefore it becomes a single string. I tried using isSpace function but I don't know exactly how to implement it in this case.



What is it that I am doing wrong? I get this output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orangeappleapple"]


But I want to achieve the below output:



λ> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]






haskell






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 21 '17 at 14:10









AJFarmar

8,87622752




8,87622752










asked Dec 21 '17 at 13:57









Big SmileBig Smile

643514




643514













  • What with tabs, ..

    – Willem Van Onsem
    Dec 21 '17 at 13:58











  • @WillemVanOnsem spaces between words

    – Big Smile
    Dec 21 '17 at 13:58





















  • What with tabs, ..

    – Willem Van Onsem
    Dec 21 '17 at 13:58











  • @WillemVanOnsem spaces between words

    – Big Smile
    Dec 21 '17 at 13:58



















What with tabs, ..

– Willem Van Onsem
Dec 21 '17 at 13:58





What with tabs, ..

– Willem Van Onsem
Dec 21 '17 at 13:58













@WillemVanOnsem spaces between words

– Big Smile
Dec 21 '17 at 13:58







@WillemVanOnsem spaces between words

– Big Smile
Dec 21 '17 at 13:58














1 Answer
1






active

oldest

votes


















4















I think the filter function is removing the white spaces and therefore it becomes a single string.




That is correct. As filter predicate you write x -> x `elem` ['a'..'z']. ['a'..'z'] is a list that contains lowercase letters, so for whitespace, the predicate will fail, and thus you should allow spaces as well.



We can for instance add the space character to the list:



dropNonLetters xs = words $ (filter (x -> x `elem` (' ':['a'..'z'])))) $ toLowerStr xs


But this is inelegant and does not really explain itself. The Data.Char module however ships with two functions that are interesting here: isLower :: Char -> Bool, and isSpace :: Char -> Bool. We can use this like:



dropNonLetters xs = words $ (filter (x -> isLower x || isSpace x)) $ toLowerStr xs


isLower and isSpace are not only more "descriptive" and elegant. Usually these functions will be faster than a membership check (which will usually be done in O(n)), and furthermore it will also take into account tabs, new lines, etc.



We can also perform an eta-reduction on the function:



dropNonLetters = words . (filter (x -> isLower x || isSpace x)) . toLowerStr


This then produces:



Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]


I advise you to rename the function dropNonLetters, since now it does not fully explain that it will generate a list of words. Based on the name, I would think that it only drops non-letters, not that it converts the string to lowercase nor that it constructs words.






share|improve this answer


























  • Thank you very much this worked and I will rename the function. You are missing -> in the second block of the code.

    – Big Smile
    Dec 21 '17 at 14:11











  • @BigSmile: thanks, it is fixed now :)

    – Willem Van Onsem
    Dec 21 '17 at 14:12











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47926501%2fhaskell-removing-non-letter-characters-but-ignoring-white-spaces%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









4















I think the filter function is removing the white spaces and therefore it becomes a single string.




That is correct. As filter predicate you write x -> x `elem` ['a'..'z']. ['a'..'z'] is a list that contains lowercase letters, so for whitespace, the predicate will fail, and thus you should allow spaces as well.



We can for instance add the space character to the list:



dropNonLetters xs = words $ (filter (x -> x `elem` (' ':['a'..'z'])))) $ toLowerStr xs


But this is inelegant and does not really explain itself. The Data.Char module however ships with two functions that are interesting here: isLower :: Char -> Bool, and isSpace :: Char -> Bool. We can use this like:



dropNonLetters xs = words $ (filter (x -> isLower x || isSpace x)) $ toLowerStr xs


isLower and isSpace are not only more "descriptive" and elegant. Usually these functions will be faster than a membership check (which will usually be done in O(n)), and furthermore it will also take into account tabs, new lines, etc.



We can also perform an eta-reduction on the function:



dropNonLetters = words . (filter (x -> isLower x || isSpace x)) . toLowerStr


This then produces:



Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]


I advise you to rename the function dropNonLetters, since now it does not fully explain that it will generate a list of words. Based on the name, I would think that it only drops non-letters, not that it converts the string to lowercase nor that it constructs words.






share|improve this answer


























  • Thank you very much this worked and I will rename the function. You are missing -> in the second block of the code.

    – Big Smile
    Dec 21 '17 at 14:11











  • @BigSmile: thanks, it is fixed now :)

    – Willem Van Onsem
    Dec 21 '17 at 14:12
















4















I think the filter function is removing the white spaces and therefore it becomes a single string.




That is correct. As filter predicate you write x -> x `elem` ['a'..'z']. ['a'..'z'] is a list that contains lowercase letters, so for whitespace, the predicate will fail, and thus you should allow spaces as well.



We can for instance add the space character to the list:



dropNonLetters xs = words $ (filter (x -> x `elem` (' ':['a'..'z'])))) $ toLowerStr xs


But this is inelegant and does not really explain itself. The Data.Char module however ships with two functions that are interesting here: isLower :: Char -> Bool, and isSpace :: Char -> Bool. We can use this like:



dropNonLetters xs = words $ (filter (x -> isLower x || isSpace x)) $ toLowerStr xs


isLower and isSpace are not only more "descriptive" and elegant. Usually these functions will be faster than a membership check (which will usually be done in O(n)), and furthermore it will also take into account tabs, new lines, etc.



We can also perform an eta-reduction on the function:



dropNonLetters = words . (filter (x -> isLower x || isSpace x)) . toLowerStr


This then produces:



Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]


I advise you to rename the function dropNonLetters, since now it does not fully explain that it will generate a list of words. Based on the name, I would think that it only drops non-letters, not that it converts the string to lowercase nor that it constructs words.






share|improve this answer


























  • Thank you very much this worked and I will rename the function. You are missing -> in the second block of the code.

    – Big Smile
    Dec 21 '17 at 14:11











  • @BigSmile: thanks, it is fixed now :)

    – Willem Van Onsem
    Dec 21 '17 at 14:12














4












4








4








I think the filter function is removing the white spaces and therefore it becomes a single string.




That is correct. As filter predicate you write x -> x `elem` ['a'..'z']. ['a'..'z'] is a list that contains lowercase letters, so for whitespace, the predicate will fail, and thus you should allow spaces as well.



We can for instance add the space character to the list:



dropNonLetters xs = words $ (filter (x -> x `elem` (' ':['a'..'z'])))) $ toLowerStr xs


But this is inelegant and does not really explain itself. The Data.Char module however ships with two functions that are interesting here: isLower :: Char -> Bool, and isSpace :: Char -> Bool. We can use this like:



dropNonLetters xs = words $ (filter (x -> isLower x || isSpace x)) $ toLowerStr xs


isLower and isSpace are not only more "descriptive" and elegant. Usually these functions will be faster than a membership check (which will usually be done in O(n)), and furthermore it will also take into account tabs, new lines, etc.



We can also perform an eta-reduction on the function:



dropNonLetters = words . (filter (x -> isLower x || isSpace x)) . toLowerStr


This then produces:



Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]


I advise you to rename the function dropNonLetters, since now it does not fully explain that it will generate a list of words. Based on the name, I would think that it only drops non-letters, not that it converts the string to lowercase nor that it constructs words.






share|improve this answer
















I think the filter function is removing the white spaces and therefore it becomes a single string.




That is correct. As filter predicate you write x -> x `elem` ['a'..'z']. ['a'..'z'] is a list that contains lowercase letters, so for whitespace, the predicate will fail, and thus you should allow spaces as well.



We can for instance add the space character to the list:



dropNonLetters xs = words $ (filter (x -> x `elem` (' ':['a'..'z'])))) $ toLowerStr xs


But this is inelegant and does not really explain itself. The Data.Char module however ships with two functions that are interesting here: isLower :: Char -> Bool, and isSpace :: Char -> Bool. We can use this like:



dropNonLetters xs = words $ (filter (x -> isLower x || isSpace x)) $ toLowerStr xs


isLower and isSpace are not only more "descriptive" and elegant. Usually these functions will be faster than a membership check (which will usually be done in O(n)), and furthermore it will also take into account tabs, new lines, etc.



We can also perform an eta-reduction on the function:



dropNonLetters = words . (filter (x -> isLower x || isSpace x)) . toLowerStr


This then produces:



Prelude Data.Char> dropNonLetters "ORANGE, apple! APPLE!!"
["orange","apple","apple"]


I advise you to rename the function dropNonLetters, since now it does not fully explain that it will generate a list of words. Based on the name, I would think that it only drops non-letters, not that it converts the string to lowercase nor that it constructs words.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 14 '18 at 2:01









Jon Purdy

38.1k768125




38.1k768125










answered Dec 21 '17 at 14:03









Willem Van OnsemWillem Van Onsem

147k16141231




147k16141231













  • Thank you very much this worked and I will rename the function. You are missing -> in the second block of the code.

    – Big Smile
    Dec 21 '17 at 14:11











  • @BigSmile: thanks, it is fixed now :)

    – Willem Van Onsem
    Dec 21 '17 at 14:12



















  • Thank you very much this worked and I will rename the function. You are missing -> in the second block of the code.

    – Big Smile
    Dec 21 '17 at 14:11











  • @BigSmile: thanks, it is fixed now :)

    – Willem Van Onsem
    Dec 21 '17 at 14:12

















Thank you very much this worked and I will rename the function. You are missing -> in the second block of the code.

– Big Smile
Dec 21 '17 at 14:11





Thank you very much this worked and I will rename the function. You are missing -> in the second block of the code.

– Big Smile
Dec 21 '17 at 14:11













@BigSmile: thanks, it is fixed now :)

– Willem Van Onsem
Dec 21 '17 at 14:12





@BigSmile: thanks, it is fixed now :)

– Willem Van Onsem
Dec 21 '17 at 14:12


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47926501%2fhaskell-removing-non-letter-characters-but-ignoring-white-spaces%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Danny Elfman

Lugert, Oklahoma