【问题标题】:Haskell foldWhile or reduceWhile without list function?Haskell foldWhile 或 reduceWhile 没有列表功能?
【发布时间】:2013-11-07 20:32:08
【问题描述】:

我正在寻找一种类似于“foldWhile”的 haskell 函数或模式,但它使用函数输出而不是折叠列表。一些代码可能会更好地解释它。

简化和伪:

nums :: [Integer]
nums = [1]

cond :: v -> [Integer] -> Bool
cond v ls = elem v ls

func :: x -> ls -> [Integer]
func x ls = x `some_op` ls

而且我需要一种应用模式,例如:

(cond 1 num) && func x num -> num'
(cond 1 num') && func x num' -> num''
(cond 1 num'') && func x num'' -> num'''
...

一旦 cond 返回 False,产生最后一个 num。

任何帮助将不胜感激,在此先感谢。

【问题讨论】:

    标签: algorithm haskell functional-programming


    【解决方案1】:

    我想你想要iteratetakeWhile 的组合:

    iterate :: (a -> a) -> a -> [a]
    takeWhile (a -> Bool) -> [a] -> [a]
    
    iterateWhile :: (a -> a) -> (a -> Bool) -> a -> [a]
    iterateWhile func cond = takeWhile cond . iterate func
    

    在您的情况下,您希望将其用作

    lastWhere :: (a -> a) -> (a -> Bool) -> a -> a
    lastWhere func cond = last . iterateWhile func cond
    
    main = do
        let x = lastWhere (+1) (<10) 1
        print x
        -- prints "9"
    

    您可能可以通过折叠来做到这一点,但是当您已经有了这个解决方案时,为什么还要麻烦呢?如果评估条件与生成值是分开的,那么将这两个问题分开,而不是试图将它们联系在一起。这就是iterateWhile 所做的。由于它是惰性求值的,因此它只会在找到不满足条件的值之前生成值,并且只需要一个循环即可。

    由于iterateWhile 生成了一个所有满足该条件的元素列表,因此您可以简单地获取最后一个元素。如果您需要第一个失败的元素,我会这样做

    firstWhere :: (a -> a) -> (a -> Bool) -> a -> a
    firstWhere func cond = head . dropWhile cond . iterate func
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 2012-06-15
      • 1970-01-01
      • 2022-01-24
      • 2020-03-18
      • 2019-08-03
      • 1970-01-01
      相关资源
      最近更新 更多