如何在Haskell的替换中应用多个案例?
我编写了一个函数,以便能够在Haskell中清除要处理的字号。它需要能够将如何在Haskell的替换中应用多个案例?,haskell,replace,Haskell,Replace,我编写了一个函数,以便能够在Haskell中清除要处理的字号。它需要能够将-更改为空格(即45变为45)并删除其他非字母。我可以递归地定义它,但我真的想做一些更干净的事情 clean :: String -> String clean "" = "" clean ('-':cs) = ' ' : clean cs clean (c:cs) | isLetter c = c : clean cs | otherwise = clean cs 这导致我定义了一个自定义过
-
更改为空格(即45变为45)并删除其他非字母。我可以递归地定义它,但我真的想做一些更干净的事情
clean :: String -> String
clean "" = ""
clean ('-':cs) = ' ' : clean cs
clean (c:cs)
| isLetter c = c : clean cs
| otherwise = clean cs
这导致我定义了一个自定义过滤器,并基于对的注释定义了替换自,因为我已经在使用Data.List.Split
clean :: String -> String
clean = filter (\c -> isLetter c || c == ' ') . replace "-" " " . filter (/= ' ')
where
replace :: String -> String -> String -> String
replace old new = intercalate new . splitOn old
这个版本从整体上来说更混乱。此外,此版本不会删除原始字符串中的空格。是一种不同的约定或内置的东西,允许我使用干净的一行程序来实现这一点吗?处理列表最强大的功能之一是(也称为
>=
)。您可以这样编写clean
函数:
clean :: String -> String
clean = concatMap (\c -> if c == '-' then " " else [c | isLetter c])
这里有两件事:
filter
和replace
的管道来实现这一点:
import Data.Bool(bool)
import Data.Char(isLetter)
map (\x -> bool ' ' x (x /= '-')) . filter (\x -> isLetter x || x == '-')
-- \____________ __________________/ \______________ ____________________/
-- v v
-- (2) (1)
我们可以使用列表理解来进行映射和筛选,如:
import Data.Bool(bool)
import Data.Char(isLetter)
clean l = [bool ' ' x (x /= '-') | x <- l, isLetter x || x == '-']
因此,如果
x
不是字母和连字符,我们将x
的映射连接到”
,如果x
不是字母和连字符,则连接空字符串,或者连接到[x]
(因此是一个单字符字符串)casex
是一个字母。这是列表monad中do
表示法的一个很好的用例
clean :: String -> String
clean string = do
character <- string -- For each character in the string...
case character of
'-' -> " " -- If it’s a dash, replace with a space.
c | isLetter c -> pure c -- If it’s a letter, return it.
_ -> [] -- Otherwise, discard it.
最后,请注意,
isleter
为所有Unicode字母返回true。如果您只关心ASCII,您可能希望使用isAscii c&&isleter c
,或isAsciiUpper c | | isAsciiLower c
谢谢!我以前从未遇到过bool
。看起来它基本上是一个if-else?@BrainFRZ:它是Bool
的一个亚同构,但对于布尔型,它确实像if-then-else
,带有Bool
。
clean :: String -> String
clean string = do
character <- string -- For each character in the string...
case character of
'-' -> " " -- If it’s a dash, replace with a space.
c | isLetter c -> pure c -- If it’s a letter, return it.
_ -> [] -- Otherwise, discard it.
if
| character == '-' -> " "
| isLetter character -> pure character
| otherwise -> []