我觉得我的愿望很前卫。
所以我有一个字符串,例如“abc1abc2abc3” 我想用给定数字的 Char 'X' 时间替换每个数字。 所以 "abc1abc2abc3" -> "abcXabcXXabcXXX"
我知道我只得到整数 <9
所以我想这样做:
myFunction givenString = let
replaceEveryNumber '1' = 'X'
replaceEveryNumber '8' = "XXXXXXXX"
replaceEveryNumber c = c
in map replaceEveryNumber myFunction
是的,由于类型不同,这实际上不起作用。
我也可以根据需要将类似的函数应用于 [String]。所以我可以从上面的代码 '1' = 'X' 改为 "1" = "X" 等等,但这里的问题是如果我有 ["abc2abc", "8"] 结果是 [" abc2abc", "XXXXXXXX"] 所以它忽略了 !!0 中字符串中的字符,我想这是有道理的,但我仍然不知道如何正确地做到这一点。
希望有人能帮帮我,谢谢!
答案 0 :(得分:2)
这里有几个问题。您不是在 givenString
上映射,而是在 myFunction
上映射。由于 myFunction
是一个函数,所以它不起作用。因此,我们应该将映射表达式替换为:
myFunction givenString = let … in map replaceEveryNumber givenString
此外,replaceEveryNumber
只能返回一种类型的值,但是您的函数返回一个 Char
,而其他行返回一个 String
。由于您的函数应该能够返回多个 Char
的序列,因此我们应该为每一行返回一个字符串。对于 c
,我们需要将其包装在一个单例列表中,以将 Char
转换为具有该字符的 String
:
myFunction givenString = let
replaceEveryNumber '1' = "X"
replaceEveryNumber '2' = "XX"
replaceEveryNumber '3' = "XXX"
replaceEveryNumber '4' = "XXXX"
replaceEveryNumber '5' = "XXXXX"
replaceEveryNumber '6' = "XXXXXX"
replaceEveryNumber '7' = "XXXXXXX"
replaceEveryNumber '8' = "XXXXXXXX"
replaceEveryNumber c = [c]
in map replaceEveryNumber givenString
现在这将生成一个 String
列表,例如:
Prelude> myFunction "abc1abc2abc3"
["a","b","c","X","a","b","c","XX","a","b","c","XXX"]
我们唯一需要做的就是连接这些字符串。我们可以使用 concat :: [[a]] -> [a]
,但我们也可以使用 concatMap :: (a -> [b]) -> [a] -> [b]
:
myFunction givenString = let
replaceEveryNumber '1' = "X"
replaceEveryNumber '2' = "XX"
replaceEveryNumber '3' = "XXX"
replaceEveryNumber '4' = "XXXX"
replaceEveryNumber '5' = "XXXXX"
replaceEveryNumber '6' = "XXXXXX"
replaceEveryNumber '7' = "XXXXXXX"
replaceEveryNumber '8' = "XXXXXXXX"
replaceEveryNumber c = [c]
in concatMap replaceEveryNumber givenString
最后,我们不需要为每个数字编写子句。我们可以使用 replicate
和 digitToInt
等函数。我把它留作练习。