【问题标题】:Manipulating list after function performs recursion在函数执行递归后操作列表
【发布时间】:2013-02-24 05:54:11
【问题描述】:

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

提前非常感谢!

【问题讨论】:

    标签: haskell function-composition


    【解决方案1】:

    首先,您的keepAll 更容易写成

    keepAll y = filter (y==)
    

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

    length (keepAll 'a' "abrakadabra")
    

    应该是 5。


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

    (f . g)
    

    【讨论】:

    • 感谢您的回复。实施并不重要。我正在寻找一个普遍的答案,比如说我想在递归后将函数init 应用于列表。
    • 回答了一般性问题。
    • 它是“将我的左参数应用于我的右参数的应用结果”运算符。
    • .运算符将两个函数组合在一起。所以 (f . g) x 和 f (g x) 一样
    • 所以我可以做类似(length . keepAll y xs) 的事情吗?从递归中获取输出列表的长度?
    【解决方案2】:

    您正在寻找function composition.

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

    f (g x)
    

    或者

    (f . g) x
    

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

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

    【讨论】:

      【解决方案3】:

      除了一般情况下的函数组合外,您还可以将 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]     -- 内部结果的初始化,[3,3,3,3]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-09
        • 2021-12-11
        • 2019-12-21
        • 2021-11-11
        • 1970-01-01
        • 2021-08-24
        • 2011-10-16
        • 2011-07-13
        相关资源
        最近更新 更多