在增加

时间:2016-04-19 02:27:44

标签: list haskell functional-programming

我有一个值列表,我希望在值增加时从中获取。我假设它总是占据列表的头部,然后将它与下一个值进行比较。只要这种情况持续增加,该功能将继续使用。在到达小于或等于前一个值的列表元素时,返回列表。

takeIncreasing :: (Ord a) => [a] -> [a]
takeIncreasing [1,2,3,4,3,5,6,7,8] -- Should return [1,2,3,4]

折叠可以将积累的last元素与下一个值进行比较,如果条件满足则追加,但会继续到列表的末尾。我希望函数在第一个实例中停止不满足约束。

这似乎是monad的应用程序,但无法确定现有的monad是否实现了这一点。

4 个答案:

答案 0 :(得分:9)

  

折叠[...]将继续到列表的末尾。我希望函数在第一个实例中停止不满足约束。

右折可能会短路:

>>> print(a)
\THISTAG[arg1=1,argtwo]{WANT0}
% \THISTAG[arg1=1,argtwo]{NOTWANT}
% blah blah \THISTAG[arg1=1,argtwo]{NOTWANT}
\THISTAG[arg1=1,argtwo]{WANT1}\THISTAG[arg1=1,argtwo]{WANT2}\stuff
\sometag{stuff I don't want}[{\THISTAG[arg1=1,argtwo]{WANT3}}]{more stuff I don'    t want}
\THISTAG[arg1=1,argtwo]{OBV_WANT}
>>>
>>> re.findall(r'\\THISTAG\[.+?\]{([^N].+?)}', a,re.MULTILINE)
['WANT0', 'WANT1', 'WANT2', 'WANT3', 'OBV_WANT']

然后,

fun :: Ord a => [a] -> [a]
fun []     = []
fun (x:xs) = x: foldr go (const []) xs x
    where go x f i = if i < x then x: f x else []

或无限大小列表:

\> fun [1,2,3,4,3,undefined]
[1,2,3,4]

答案 1 :(得分:4)

右侧折叠是神奇的,所以你甚至不必在列表上进行模式匹配。

twi xs = foldr go (const []) xs Nothing where
  go x _ (Just prev)
    | x < prev = []
  go x r _ = x : r (Just x)

答案 2 :(得分:3)

或者说IMO的代码复杂性要低一些:

takeIncreasing :: Ord x => [x] -> [x]
takeIncreasing (x:x':xs) | x < x'    = x : takeIncreasing (x':xs)
                         | otherwise = [x]
takeIncreasing xs = xs

这个比以前的建议稍微聪明一点。我喜欢不聪明的代码。

答案 3 :(得分:2)

没有折叠的解决方案:

takeIncreasing :: Ord a => [a] -> [a]
takeIncreasing [] = []
takeIncreasing (x:xs) = (x :) . map snd . takeWhile (uncurry (<)) $ zip (x:xs) xs