简体   繁体   English

在 Haskell List Comprehensions 中做一些替换

[英]Do some replacement in Haskell List Comprehensions

My questions is if I put in a string containing such as Hello, today is a Nice Day!!我的问题是,如果我输入一个包含诸如Hello, today is a Nice Day!!类的字符串Hello, today is a Nice Day!! How could I get rid of spaces and punctuation and also replacing the uppercase letters with lowercase?我怎样才能摆脱空格和标点符号并用小写字母替换大写字母?

I know how to delete them but not how to replace them.我知道如何删除它们但不知道如何替换它们。

Also to get rid of the punctuation.还要去掉标点符号。

Sorry I don't know how to mess around with strings, only numbers.抱歉,我不知道如何处理字符串,只知道如何处理数字。

testList xs = [if x = [,|.|?|!] then " "  | x<-xs] 
import Data.Char

If you want convert the punctuation to space and the characters from upper case to lower case:如果要将标点符号转换为空格并将字符从大写转换为小写:

testList xs = [if x `elem` ",.?!" then ' ' else toLower x | x<-xs]

Example: testList "TeST,LiST!" == "test list "示例: testList "TeST,LiST!" == "test list " testList "TeST,LiST!" == "test list "

If you want to delete the punctuation and convert the characters from upper case to lower case:如果要删除标点符号并将字符从大写转换为小写:

testList2 xs = [toLower x | x<-xs, not (x `elem` ",.?!")]

Example: testList2 "Te..S,!t LiS?T" == "test list"示例: testList2 "Te..S,!t LiS?T" == "test list"

If you don't want or can not import Data.Char, this is an implementation of toLower:如果你不想或不能导入 Data.Char,这是 toLower 的一个实现:

toLower' :: Char -> Char
toLower' char 
    | isNotUppercase = char -- no change required
    | otherwise = toEnum (codeChar + diffLowerUpperChar) -- char lowered
    where
      codeChar = fromEnum char -- each character has a numeric code
      code_A = 65
      code_Z = 90
      code_a = 97
      isNotUppercase = codeChar < code_A || codeChar > code_Z
      diffLowerUpperChar = code_a - code_A

I've been without writing a code in Haskell for a long time, but the following should remove the invalid characters (replace them by a space) and also convert the characters from Uppercase to Lowercase:我已经很长时间没有在 Haskell 中编写代码了,但是以下内容应该删除无效字符(用空格替换它们)并将字符从大写转换为小写:

import Data.Char

replace invalid xs = [if elem x invalid then ' ' else toLower x | x <- xs]

Another way of doing the same:另一种方法:

repl invalid [] = []
repl invalid (x:xs) | elem x invalid = ' ' : repl invalid xs
                    | otherwise      = toLower x : repl invalid xs

You can call the replace (or repl ) function like this:您可以像这样调用replace (或repl )函数:

replace ",.?!" "Hello, today is a Nice Day!!"

The above code will return:上面的代码将返回:

"hello  today is a nice day  "

Edit: I'm using the toLower function from Data.Char in Haskell, but if you want to write it by yourself, check here on Stack Overflow.编辑:我使用的toLower从功能Data.Char在Haskell,但如果你想自己写吧,点击这里堆栈溢出。 That question has been asked before.这个问题以前有人问过。

You will find the functions you need in Data.Char :您将在Data.Char找到您需要的功能:

import Data.Char

process str = [toLower c | c <- str , isAlpha c]

Though personally, I think the function compositional approach is clearer:虽然我个人认为函数组合方法更清晰:

process = map toLower . filter isAlpha

To get rid of the punctuation you can use a filter like this one要摆脱标点符号,您可以使用这样的过滤器

[x | x<-[1..10], x `mod` 2 == 0]

The "if" you are using won't filter.您使用的“如果”不会过滤。 Putting an if in the "map" part of a list comprehension will only seve to choose between two options but you can't filter them out there.在列表推导式的“地图”部分放置一个 if 只会在两个选项之间进行选择,但您无法将它们过滤掉。

As for converting things to lowercase, its the same trick as you can already pull off in numbers:至于将事物转换为小写,它与您已经可以在数字上实现相同的技巧:

[x*2 | x <- [1..10]]

Here's a version without importing modules, using fromEnum and toEnum to choose which characters to allow:这是一个没有导入模块的版本,使用 fromEnum 和 toEnum 来选择允许的字符:

testList xs = 
  filter (\x -> elem (fromEnum x) ([97..122] ++ [32] ++ [48..57])) $ map toLower' xs 
    where toLower' x = if elem (fromEnum x) [65..90] 
                          then toEnum (fromEnum x + 32)::Char 
                          else x

OUTPUT:
*Main> testList "Hello, today is a Nice Day!!"
"hello today is a nice day"

For a module-less replace function, something like this might work:对于无模块替换功能,这样的事情可能会起作用:

myReplace toReplace xs = map myReplace' xs where
  myReplace' x
    | elem (fromEnum x) [65..90] = toEnum (fromEnum x + 32)::Char
    | elem x toReplace           = ' '
    | otherwise                  = x

OUTPUT:
*Main> myReplace "!," "Hello, today is a Nice Day!! 123"
"hello  today is a nice day   123"

Using Applicative Style使用应用风格

A textual quote from book "Learn You a Haskell for Great Good!":来自“Learn You a Haskell for Great Good!”一书的文字引述:

Using the applicative style on lists is often a good replacement for list comprehensions.在列表上使用 applicative 样式通常是列表推导式的良好替代。 In the second chapter, we wanted to see all the possible products of [2,5,10] and [8,10,11], so we did this:在第二章中,我们想看到 [2,5,10] 和 [8,10,11] 的所有可能乘积,所以我们这样做了:

[ x*y | x <- [2,5,10], y <- [8,10,11]]         

We're just drawing from two lists and applying a function between every combination of elements.我们只是从两个列表中绘制并在每个元素组合之间应用一个函数。 This can be done in the applicative style as well:这也可以在应用风格中完成:

(*) <$> [2,5,10] <*> [8,10,11]

This seems clearer to me, because it's easier to see that we're just calling * between two non-deterministic computations.这对我来说似乎更清楚,因为更容易看出我们只是在两个非确定性计算之间调用 * 。 If we wanted all possible products of those two lists that are more than 50, we'd just do:如果我们想要这两个列表中超过 50 个的所有可能产品,我们会这样做:

filter (>50) $ (*) <$> [2,5,10] <*> [8,10,11]
-- [55,80,100,110]

Functors, Applicative Functors and Monoids 函子、应用函子和幺半群

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM