函数执行递归后操作列表

时间:2013-02-23 18:16:46

标签: haskell function-composition

我是Haskell的新手,我正在尝试在列表上执行一些递归函数,并且在递归完成后,我想从递归中访问输出列表以执行其他操作。

例如,下面的函数接受一个值和一个列表,它返回一个只包含要保留的值的列表,丢弃所有其他值。

我想做的是,了解在递归发生后如何访问输出列表,这样我就可以继续操作了。

类似的东西:

//recursive function here

//get length of output list from recursive function
length list

我的功能

keepAll _ [] = []
keepAll y (x:xs) | x==y = y:keepAll y xs
                 | otherwise = keepAll y xs

非常感谢提前!

3 个答案:

答案 0 :(得分:5)

首先,您的keepAll更容易被写为

keepAll y = filter (y==)

其次,您可以将length或其他任何内容应用于结果,例如

length (keepAll 'a' "abrakadabra")

应为5。


因此,您的问题“如何将f应用于g的结果”的一般答案是

(f . g)

答案 1 :(得分:3)

您正在寻找function composition.

一个函数的输出可以作为输入传递给另一个函数,如下所示:

f (g x)

或者

(f . g) x

其中函数g的输出类型与f。

的输入类型相同

(。)运算符将两个这样的函数组合成一个管道。

答案 2 :(得分:1)

除了一般情况的函数组合之外,您还可以将一个特定的keepAll结果赋给变量并在以后使用该值:

outputList = keepAll 3 [1,2,3,3,3,4,5,3]
print (init outputList)   >> [3,3,3]
print (length outputList) >> 4


如果要访问函数内部递归的输出列表,可能需要将递归委托给内部的“帮助器”函数,例如:

keepSome y (x:xs) = keepAll y (x:xs)
  where keepAll _ [] = []
        keepAll y (x:xs) | x==y = y:keepAll y xs
                         | otherwise = keepAll y xs

现在您可以更改第一行,以便将“init”应用于递归结果,如您所建议的那样:

keepSome y (x:xs) = init $ keepAll y (x:xs)
  where keepAll _ [] = []
        keepAll y (x:xs) | x==y = y:keepAll y xs
                         | otherwise = keepAll y xs

例如,你也可以命名递归的输出列表,“outputList”,如果它使你更容易使用,并将init应用于:

keepSome y (x:xs) = init outputList
  where outputList = keepAll y (x:xs)
        keepAll _ [] = []
        keepAll y (x:xs) | x==y = y:keepAll y xs
                         | otherwise = keepAll y xs

示例输出:
*主> keepSome 3 [1,2,3,3,3,4,5,3]
[3,3,3] - 内部结果的内容,[3,3,3,3]