【问题标题】:Does Haskell have a takeUntil function?Haskell 有 takeUntil 函数吗?
【发布时间】:2014-04-23 17:32:21
【问题描述】:

目前我正在使用

takeWhile (\x -> x /= 1 && x /= 89) l

从列表中获取最多为 1 或 89 的元素。但是,结果不包括这些标记值。 Haskell 是否有一个标准函数来提供takeWhile 的这种变体,其中包括结果中的哨兵?到目前为止,我使用 Hoogle 进行的搜索都没有结果。

【问题讨论】:

    标签: haskell functional-programming


    【解决方案1】:

    既然你问的是标准函数,no。但也没有包含takeWhileInclusive 的包,但这真的很简单:

    takeWhileInclusive :: (a -> Bool) -> [a] -> [a]
    takeWhileInclusive _ [] = []
    takeWhileInclusive p (x:xs) = x : if p x then takeWhileInclusive p xs
                                             else []
    

    你唯一需要做的就是不管谓词是否返回 True 都取值,并且只使用谓词作为延续因子:

    *Main> takeWhileInclusive  (\x -> x /= 20) [10..]
    [10,11,12,13,14,15,16,17,18,19,20]
    

    【讨论】:

    • 我对 Haskell 还很陌生,无论如何自己实现这些东西可能是一个很好的练习。感谢您的建议。
    • 我知道这是一篇旧帖子,但他的功能并不能完全满足一般要求,即使它适用于这种特定情况....例如takeWhileInclusive (>1) [2,2,2,2,2,1,1,1,1,1,1,1] 将返回整个列表这不完全是takeWhile + sentinel
    • @matt err,不。 takeWhileInclusive 只返回第一个哨兵,而不是整个列表:ideone.com/wD0ULx。结果中只有一个1(哨兵)。
    • 对不起,我的意思是(>=1) 在那种情况下.. 它不是takeWhile + sentinel ... 例如你不能用它来接受collatz 函数
    • @matt 使用(>=1),所有元素都适合谓词,takeWhile (>= 1) xs == takeWhileInclusive (>= 1) xs 适合xs = [2,2,2,2,1,1,1,1]。不过,您可能想针对您的问题提出一个新问题。
    【解决方案2】:

    span是你想要的吗?

    matching, rest = span (\x -> x /= 1 && x /= 89) l
    

    然后看看rest的头。

    【讨论】:

    • 在这种情况下,我认为您需要 span 而不是 break 以符合 OP 的规范。
    • 啊,是的,当然。我刚刚想到break 的谓词是颠倒的,但我不知道span。我会相应地更新答案!
    • @sanityinc:我也有这个想法,但你需要小心一点,因为rest 可能是[]
    • @Zeta 确实是的——出于这个原因,我在示例中避免了对rest 的缺点匹配。总体而言,您的显式解决方案可能是更好的选择。
    【解决方案3】:

    我发现实现这一点的最短方法是使用 span 并在它之前添加一个函数,该函数获取 span 的结果并将结果元组的第一个元素与第二个元素的头部合并结果元组。 整个表达式看起来像这样:

    (\(f,s) -> f ++ [head s]) $ span (\x -> x /= 1 && x /= 89) [82..140]
    

    这个表达式的结果是

    [82,83,84,85,86,87,88,89]
    

    span 返回的元组的第一个元素是 takeWhile 将为这些参数返回的列表,第二个元素是具有剩余值的列表,因此我们只需将第二个列表中的头部添加到我们的第一个列表中。

    【讨论】:

    • 尝试使用空列表调用它。看看出了什么问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 2018-04-30
    • 2016-11-27
    相关资源
    最近更新 更多