Real World Haskell, chapter 4, page 98 of the print询问 words
可以使用折叠来实现,这也是我的问题:
可能吗?如果不是,为什么?如果是,怎么做?
我想出了以下内容,这是基于每个非空格都应该添加到输出列表中的最后一个单词的想法(这发生在 otherwise
保护中),并且空格应该触发附加如果还没有,则将 emtpy 单词添加到输出列表中(这在 if
- then
- else
中处理)。
myWords :: String -> [String]
myWords = foldr step [[]]
where
step x yss@(y:ys)
| x == ' ' = if y == "" then yss else "":yss
| otherwise = (x:y):ys
显然,这种解决方案是错误的,因为输入字符串中的前导空格会导致输出字符串列表中出现一个前导空字符串。在上面的链接中,我为其他读者研究了几个建议的解决方案,其中许多与我的解决方案类似,但它们通常“后处理”折叠的输出,例如
tail
如果有一个空的前导字符串,则输入它。其他方法使用元组(实际上只是对),因此折叠处理对并且可以很好地处理前导/尾随空格。
在所有这些方法中,
foldr
(或另一个折叠,fwiw)不是提供开箱即用的最终输出的函数;总是有其他东西必须以某种方式调整输出。因此我回到最初的问题并询问是否真的可以实现
words
(以它正确处理尾随/前导/重复空格的方式)使用折叠。通过使用折叠,我的意思是折叠功能必须是最外层的功能:myWords :: String -> [String]
myWords input = foldr step seed input
最佳答案
如果我理解正确,您的要求包括
(1) words "a b c" == words " a b c" == ["a", "b", "c"]
(2) words "xa b c" == ["xa", "b", "c"] /= ["x", "a", "b", "c"] == words "x a b c"
这意味着我们不能拥有
words = foldr step base
对于任何
step
和 base
.确实,如果我们有那个,那么
words "xa b c"
= def words and foldr
step 'x' (words "a b c")
= (1)
step 'x' (words " a b c")
= def words and foldr
words "x a b c"
这与(2)相矛盾。
在
foldr
之后你肯定需要一些后期处理。 .
关于haskell - 折叠后是否可以在没有后处理步骤的情况下实现单词功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61496273/