在函数式编程中使用计数器进行迭代?

时间:2016-10-12 10:47:58

标签: haskell iteration

我正在浏览[Char]列表,我想知道执行迭代的最佳方法。

此函数以递归方式调用自身,并将每次迭代减少的计数器传回给自己。

它仅用于说明目的,因此每个Char始终返回True:

text = ["abcsdsdsdsd"]

exampleFunction :: Int -> String -> [Bool]
exampleFunction textlen text
  | textlen >= 0        = True : exampleFunction (textlen - 1) text
  | otherwise   = []

使用' textlen'作为一个计数器似乎相当必要,这是最好的方式和/或最像Haskell的实现吗?

1 个答案:

答案 0 :(得分:2)

计数器不是必需的。列表的长度并不是特别重要;您只需使用它来确定列表是否为非空(textlen >= 0)。你可以通过参数本身的模式匹配来做同样的事情。

exampleFunction :: [String] -> [Bool]
exampleFunction (x:xs) = True : exampleFunction xs
exampleFunction []  = []

正如评论中所指出的,这个特定的递归方案被抽象为map函数:

exampleFunction :: [String] -> [Bool]
exampleFunction xs = map (const True) xs

其中const True返回一个返回True的函数,无论其参数是什么。 (const True也可以写成显式的lambda表达式(\_ -> True)。map将此函数应用于xs的每个元素,并将结果合并到一个新列表中。 / p>

其他递归方案捕获不同类型的递归(filterfoldr等),因此尽管总是可以编写显式递归函数来完成任务,但您通常可以避免它使用适当的高阶函数。

我有点滥用术语递归方案;可以将mapfilter视为foldr的特殊情况,这是一个称为 catamorphism 的一般递归方案的示例。