【发布时间】:2014-04-23 17:32:21
【问题描述】:
目前我正在使用
takeWhile (\x -> x /= 1 && x /= 89) l
从列表中获取最多为 1 或 89 的元素。但是,结果不包括这些标记值。 Haskell 是否有一个标准函数来提供takeWhile 的这种变体,其中包括结果中的哨兵?到目前为止,我使用 Hoogle 进行的搜索都没有结果。
【问题讨论】:
标签: haskell functional-programming
目前我正在使用
takeWhile (\x -> x /= 1 && x /= 89) l
从列表中获取最多为 1 或 89 的元素。但是,结果不包括这些标记值。 Haskell 是否有一个标准函数来提供takeWhile 的这种变体,其中包括结果中的哨兵?到目前为止,我使用 Hoogle 进行的搜索都没有结果。
【问题讨论】:
标签: haskell functional-programming
既然你问的是标准函数,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]
【讨论】:
takeWhileInclusive (>1) [2,2,2,2,2,1,1,1,1,1,1,1] 将返回整个列表这不完全是takeWhile + sentinel
takeWhileInclusive 只返回第一个哨兵,而不是整个列表:ideone.com/wD0ULx。结果中只有一个1(哨兵)。
(>=1) 在那种情况下.. 它不是takeWhile + sentinel ... 例如你不能用它来接受collatz 函数
(>=1),所有元素都适合谓词,takeWhile (>= 1) xs == takeWhileInclusive (>= 1) xs 适合xs = [2,2,2,2,1,1,1,1]。不过,您可能想针对您的问题提出一个新问题。
span是你想要的吗?
matching, rest = span (\x -> x /= 1 && x /= 89) l
然后看看rest的头。
【讨论】:
span 而不是 break 以符合 OP 的规范。
break 的谓词是颠倒的,但我不知道span。我会相应地更新答案!
rest 可能是[]。
rest 的缺点匹配。总体而言,您的显式解决方案可能是更好的选择。
我发现实现这一点的最短方法是使用 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 将为这些参数返回的列表,第二个元素是具有剩余值的列表,因此我们只需将第二个列表中的头部添加到我们的第一个列表中。
【讨论】: