[Real World Haskell, chapter 4, page 98 of the print询问是否可以使用折叠实现words
,这也是我的问题:
有可能吗?如果没有,为什么?如果是,怎么办?
我提出了以下内容,其依据是每个非空格都应该放在输出列表的最后一个单词的前面(这是在otherwise
防护中发生的,并且空格应该触发追加)。如果没有一个空词,则将其插入输出列表中(在if
-then
-else
中处理)。
myWords :: String -> [String]
myWords = foldr step [[]]
where
step x ass@(a:as)
| x == ' ' = if a == "" then ass else "":ass
| otherwise = (x:a):as
显然,此解决方案是错误的,因为输入字符串中的前导空格导致字符串输出列表中的一个前导空字符串。
[在上面的链接中,我研究了为其他读者准备的几种解决方案,其中许多解决方案与我的解决方案相似,但它们通常对折页的输出进行“后处理”,例如[C0 ],如果有一个空的前导字符串。
[其他方法使用元组(实际上只是对),以便折叠处理对并可以很好地处理前导/尾随空格。
在所有这些方法中,tail
(或另一折,fwiw)不是开箱即用地提供最终输出的功能;总有其他东西必须以某种方式调整输出。
因此,我回到最初的问题,询问是否实际上可以使用折叠实现foldr
(以正确处理尾部/前导/重复空格的方式)。通过using folds,我的意思是折叠功能必须是最外面的功能:
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
这与(2)矛盾。
您肯定需要在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"
之后进行一些后期处理。
@@ chi有一个很好的论点,不,您不能使用“ a”折叠来实现单词,但是您确实说过using fold s。
foldr
最外面的功能和最里面的功能都是折叠。 ;-)