Recursively dropping elements from list in Haskell

时间:2016-02-03 04:16:32

标签: haskell recursion

Right now I'm working on a problem in Haskell in which I'm trying to check a list for a particular pair of values and return True/False depending on whether they are present in said list. The question goes as follows:

Define a function called after which takes a list of integers and two integers as parameters. after numbers num1 num2 should return true if num1 occurs in the list and num2 occurs after num1. If not it must return false.

My plan is to check the head of the list for num1 and drop it, then recursively go through until I 'hit' it. Then, I'll take the head of the tail and check that against num2 until I hit or reach the end of the list.

I've gotten stuck pretty early, as this is what I have so far:

after :: [Int] -> Int -> Int -> Bool
after x y z
    | y /= head x =  after (drop 1 x) y z

However when I try to run something such as after [1,4,2,6,5] 4 5 I get a format error. I'm really not sure how to properly word the line such that haskell will understand what I'm telling it to do.

Any help is greatly appreciated! Thanks :)

Edit 1: This is the error in question:

Program error: pattern match failure: after [3,Num_fromInt instNum_v30 4] 3 (Num_fromInt instNum_v30 2)

4 个答案:

答案 0 :(得分:3)

尝试这样的事情:

after :: [Int] -> Int -> Int -> Bool
after (n:ns) a b | n == a = ns `elem` b
                 | otherwise = after ns a b
after _      _ _ = False

基本上,函数逐个元素地遍历列表。如果它在任何时候遇到a(第一个数字),那么它会检查b是否在列表的其余部分中。如果是,则返回True,否则返回False。此外,如果它在没有看到a的情况下到达列表的末尾,则返回False

答案 1 :(得分:3)

after :: Eq a => [a] -> a -> a -> Bool
after ns a b =
  case dropWhile (/= a) ns of
    [] -> False
    _:xs -> b `elem` xs

http://hackage.haskell.org/package/base-4.8.2.0/docs/src/GHC.List.html#dropWhile

答案 2 :(得分:2)

after xs p1 p2 = [p1, p2] `isSubsequenceOf` xs

那么我们如何定义呢?填写下面的空白!

isSubsequenceOf :: Eq a => [a] -> [a] -> Bool

[] `isSubsequenceOf` _ = ?
(_ : _) `isSubsequenceOf` [] = ?
xss@(x : xs) `isSubsequenceOf` (y:ys)
  | x == y = ?
  | otherwise = ?

答案 3 :(得分:0)

   after :: [Int] -> Int -> Int -> Bool
   Prelude> let after xs a b =  elem b . tail $ dropWhile (/=a) xs

示例:

  Prelude> after   [1,2,3,4,3] 88  7
  *** Exception: Prelude.tail: empty list

因尾巴而引发异常。编写尾部很容易,因此它不会引发异常。否则它的效果非常好。

  Prelude> after  [1,2,3,4,3] 2  7
  False
  Prelude> after   [1,2,3,4,3] 2  4
  True