如果我得到一个字符串列表,例如[“ Dog”,“ red”,“ caR”,“ HELLO”],并且我想使用fold指令将小写字母转换为大写字母,反之亦然,我该如何返回字符串列表?
返回值应类似于[“ dOG”,“ RED”,“ CAr”,“ hello”]
我有这个代码
convertWords :: [String] -> String
convertWords words= foldl(\ r it ->r++foldl(\ rr iitt ->if isUpper iitt then rr++[toLower iitt] else rr++[toUpper iitt]) [] it) [] words
问题是它返回了很好的转换,但是在一个列表中,例如:
“ dOGREDCArhello”
谢谢
答案 0 :(得分:1)
如果我得到一个字符串列表,例如[“ Dog”,“ red”,“ caR”,“ HELLO”],并且我想使用fold指令将小写字母转换为大写字母,反之亦然,我该如何返回字符串列表?
如果对于给定的字符串列表,您还希望具有字符串列表,则此类函数的类型将为convertWords :: [String] -> [String]
。
对于列表中的每个String
,您需要应用另一个函数,该函数将交换大小写convertWord :: String -> String
。因此,convertWords = map convertWord
。
鉴于切换大小写仅适用于Char
和String = [Char]
,我们还需要具有convertChar :: Char -> Char
功能,所以convertWord = map convertChar
。
convertChar
的定义可能像这样:
convertChar :: Char -> Char
convertChar c | isUpper c = toLower c
| otherwise = toUpper c
最后
convertWord :: String -> String
convertWord = map convertChar
convertWords :: [String] -> [String]
convertWords = map convertWord
我们得到正确的结果:
>> convertWords ["Dog", "red", "caR", "HELLO"]
["dOG","RED","CAr","hello"]
it :: [String]
答案 1 :(得分:1)
使用if then else
来处理being upper or not being upper
的二进制条件和map
可能是这样的:
converter i = map (map(\x -> if isUpper x then toLower x else toUpper x)) i
如果您想使用foldl,我们需要查看foldl的签名:
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
因此,我们可以创建一个函数以获取String列表,一个String并在列表内返回该String的受控版本。
folder :: [String] -> String -> [String]
要留在if then else
以便更容易地看到差异,就应该像这样:
folder :: [String] -> String -> [String]
folder xs "" = []
folder xs s = xs ++ [sb s]
where sb "" = ""
sb (c:cc) = if isUpper c then toLower c : sb cc else toUpper c : sb cc
当然可以,最好更改为与后卫匹配,我让你自己决定。
有了此功能folder
,我们现在可以使用foldl
,因为签名匹配。给foldl
我们的folder
以及一个空列表和输入列表作为参数将解决此问题:
converter' xs = foldl folder [] xs