haskell - 折叠后是否可以在没有后处理步骤的情况下实现单词功能?

标签 haskell functional-programming fold

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

对于任何 stepbase .

确实,如果我们有那个,那么
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/

相关文章:

haskell - 我可以说服 stack/ghci *仅*加载本地 .ghci 文件吗?

types - Coq 数据类型 - 带括号的一对

functional-programming - 迭代连续折叠结果的惯用和功能方法是什么?

haskell - 如何减少 Haskell 应用程序中的内存使用量?

Haskell:无法匹配预期的类型错误

haskell - 从 "stack exec"获取分析文件

javascript - 在 Javascript 中使用 lambda 演算(使用教堂数字)的递归问题

ios - 在变量的 didSet 中调用可选函数是不好的做法吗?

list - 如何使用 Scheme 的 Map 函数将两个列表传递给一个函数?

haskell - 为什么 foldl 尽管是尾递归的,但似乎是有害的?