1

我是 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

提前谢谢了!

4

3 回答 3

5

首先,你keepAll更容易写成

keepAll y = filter (y==)

其次,您可以length对结果应用或其他方式,例如

length (keepAll 'a' "abrakadabra")

应该是5。


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

(f . g)
于 2013-02-23T18:21:31.387 回答
3

您正在寻找功能组合。

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

f (g x)

或者

(f . g) x

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

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

于 2013-02-23T18:26:03.833 回答
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

样本输出:
*Main> keepSome 3 [1,2,3,3,3,4,5,3]
[3,3,3] --init of the inside result, [3,3,3,3]

于 2013-02-23T19:55:10.580 回答