我有一个函数,它接受一个子字符串和一个字符串,并在字符串中查找匹配的子字符串,并将匹配的字符更改为大写.例如:
> upperCase "aaa" "---aaa---"
"---AAA---"
Run Code Online (Sandbox Code Playgroud)
我想使用这个函数,但是使用几个子串应用upperCase操作.例如:
> upperCases ["aaa", "bbb", "c"] "d---aaa---c--bbb"
"d---AAA---C--BBB"
Run Code Online (Sandbox Code Playgroud)
我正在努力理解的是我如何做到这一点.这是我最好的尝试:
upperCases [] st = st
upperCases [x] st = upperCase x st
upperCases (x:xs) st = upperCases xs st
Run Code Online (Sandbox Code Playgroud)
当我upperCases在上面的例子中使用此函数时,我得到以下不正确的输出:
"d---aaa---C--bbb"
Run Code Online (Sandbox Code Playgroud)
只更改了最后一个子字符串.这个函数有什么问题,我可以编写一个函数来执行示例操作吗?
你只是x从模式中"扔掉"了x:xs.显然,在递归到其他匹配之前,您需要先使用它!
upperCases (x:xs) st = upperCases xs $ upperCase x st
Run Code Online (Sandbox Code Playgroud)
但是,最好不要明确地写出递归.你想要的基本上是将一堆功能链接在一起.这是一个折叠:
chain :: [a -> a] -> a -> a
chain = foldr (.) id
Run Code Online (Sandbox Code Playgroud)
现在,目前你还没有功能a->a.相反,你有b->a->a,其中两个b和a实际上String.但是你可以部分地应用第一个参数,例如
[upperCase "aaa", upperCase "bbb", upperCase "c"] :: [String -> String]
Run Code Online (Sandbox Code Playgroud)
更简洁的是,这个列表可以定义为map upperCase ["aaa", "bbb", "c"].
总而言之,你需要
upperCases = foldr (.) id . map upperCase
Run Code Online (Sandbox Code Playgroud)
实际上,你甚至可以包括upperCase在折叠中:
upperCases = foldr ((.) . upperCase) id
Run Code Online (Sandbox Code Playgroud)