Haskell 折叠后不需要后处理步骤就可以实现单词功能吗?
询问是否可以使用折叠实现Haskell 折叠后不需要后处理步骤就可以实现单词功能吗?,haskell,functional-programming,fold,Haskell,Functional Programming,Fold,询问是否可以使用折叠实现单词,这也是我的问题: 可能吗?若否,原因为何?如果是,如何进行? 我提出了以下想法,这是基于这样的想法:每个非空格都应该在输出列表中的最后一个单词前加上前缀(这种情况发生在否则保护中),如果没有空格,则空格应该触发将emtpy单词追加到输出列表中(这在中处理,如果-则-否则) 显然,这种解决方案是错误的,因为输入字符串中的前导空格会导致字符串输出列表中的一个前导空字符串 在上面的链接中,我为其他读者研究了几个建议的解决方案,其中许多方案的工作原理与我的解决方案类似,但它
单词
,这也是我的问题:
可能吗?若否,原因为何?如果是,如何进行?
我提出了以下想法,这是基于这样的想法:每个非空格都应该在输出列表中的最后一个单词前加上前缀(这种情况发生在否则
保护中),如果没有空格,则空格应该触发将emtpy单词追加到输出列表中(这在中处理,如果-则-否则
)
显然,这种解决方案是错误的,因为输入字符串中的前导空格会导致字符串输出列表中的一个前导空字符串
在上面的链接中,我为其他读者研究了几个建议的解决方案,其中许多方案的工作原理与我的解决方案类似,但它们通常会“后处理”折叠的输出,例如,如果有空的前导字符串,则通过tail
ing对其进行处理
其他方法使用元组(实际上只是对),因此折叠处理对,并且可以很好地处理前导/尾随空格
在所有这些方法中,foldr
(或另一个fold,fwiw)并不是提供开箱即用的最终输出的函数;总有一些其他功能需要以某种方式调整输出
因此,我回到最初的问题,询问是否可以使用折叠来实现单词
(以正确处理尾随/前导/重复空格的方式)。使用折叠意味着折叠功能必须是最外层的功能:
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
对于任何步骤
和基础
myWords :: String -> [String]
myWords = foldr step [[]]
where
step x yss@(y:ys)
| x == ' ' = if y == "" then yss else "":yss
| otherwise = (x:y):ys
事实上,如果我们有,那么
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
@之后,您肯定需要一些后处理。chi有一个很好的论点,即您不能使用“a”折叠实现单词,但您确实说过使用折叠s
words = filterNull . words1
where
filterNull = foldr (\xs -> if null xs then id else (xs:)) []
words1 = foldr (\c -> if c == ' ' then ([]:) else consHead c) []
consHead c [] = [[c]]
consHead c (xs:xss) = (c:xs):xss
最外层和最内层的功能都是折叠。;-是。尽管这有点棘手,但如果您深入到CPS()中,您仍然可以通过使用单个foldr
来正确地完成这项工作。我以前展示过一种特殊的函数
在这类折叠中,我们的累加器,因此折叠的结果是一个函数,我们必须将它应用于同一类型的输入,这样我们才能得到最终的结果。因此,这可能算不算是最终处理阶段,因为我们在这里使用的是单个折叠,它的类型包括函数。公开辩论:)
sf
:要开始的初始函数值
go
:迭代器函数
实际上,我们并没有充分利用CPS的力量,因为我们在每一轮中都有前一个字符pc
和当前字符c
。在上面提到的chunksOf
函数中,它非常有用,每次元素的升序被打破时,它都会将[Int]
分块成[Int]
。我想你知道我的意思,但是+1因为挑剔:POr甚至[“xa”]==单词“xa”==步骤“x”(单词“a”)==步骤“x”(单词“a”)==单词“a”=[“x”,“a”]
,它的优点是可以作为任意折叠方向的有效参数
ws :: String -> [String]
ws str = foldr go sf str $ ""
where
sf :: String -> [String]
sf s = if s == " " then [""] else [s]
go :: Char -> (String -> [String]) -> (String -> [String])
go c f = \pc -> let (s:ss) = f [c]
in case pc of
"" -> dropWhile (== "") (s:ss)
otherwise -> case (pc == " ", s == "") of
(True, False) -> "":s:ss
(True, True) -> s:ss
otherwise -> (pc++s):ss
λ> ws " a b c "
["a","b","c"]