在Haskell中进行转换后创建字符串列表的问题

时间:2018-10-13 14:02:09

标签: haskell

如果我得到一个字符串列表,例如[“ 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”

谢谢

2 个答案:

答案 0 :(得分:1)

  

如果我得到一个字符串列表,例如[“ Dog”,“ red”,“ caR”,“ HELLO”],并且我想使用fold指令将小写字母转换为大写字母,反之亦然,我该如何返回字符串列表?

如果对于给定的字符串列表,您还希望具有字符串列表,则此类函数的类型将为convertWords :: [String] -> [String]

对于列表中的每个String,您需要应用另一个函数,该函数将交换大小写convertWord :: String -> String。因此,convertWords = map convertWord

鉴于切换大小写仅适用于CharString = [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