0

I need to write a function in Haskell that given a list of at least 7 elements returns a tuple containing the first and seventh element.

e.g.

Prelude> take1and7 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
(1, 7)

I've tried this

take1and7 :: [a] -> (a, a)
take1and7 [a, b, c, d, e, f, g, xs] = (a, g)

But it says that it has "non-exhaustive patterns" which I don't understand

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Huddlespith
  • 123
  • 1
  • 2
  • 8
  • 1
    you want `take1and7 (a:b:c:d:e:f:g:xs) = (a, g)` instead. (Would be happy to explain further if needed, but I see an answer has gone up since I started typing this :) ) – Robin Zigmond Feb 04 '19 at 15:20
  • 2
    Do you have to use pattern matching? An easier to read implementation would be to use `!!` – 4castle Feb 04 '19 at 16:27
  • Possible duplicate of [Haskell - Non-exhaustive patterns in case](https://stackoverflow.com/questions/8451653/haskell-non-exhaustive-patterns-in-case) – jberryman Feb 04 '19 at 23:48

1 Answers1

6
... [a, b, c, d, e, f, g, xs] = ...

is a pattern which matches an 8 elements long list. xs names the 8th element, not the rest of the list.

In case you call this function with a list of 6, 7, 9, etc. elements, the pattern won't match.

... (a: b: c: d: e: f: g: xs) = ...

is a pattern which matches a list of 7 elements or longer. xs names the rest of the list after its first 7 elements. With it, the function still won't be able to handle any list shorter than 7 elements.

The "non-exhaustive" phrasing means our function doesn't handle all possible cases.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
  • I'm now getting a new error `Occurs check: cannot construct the infinite type: a ~ [a] • In the pattern: a : b : c : d : e : f : g : xs In the pattern: [a : b : c : d : e : f : g : xs] In an equation for ‘take1and7’: take1and7 [a : b : c : d : e : f : g : xs] = (a, g) ` – Huddlespith Feb 04 '19 at 15:24
  • 4
    NB: `(a : xs)` round parens . – Will Ness Feb 04 '19 at 15:25
  • 3
    @Huddlespith looks like you misread the code in the answer. You should use`(` and `)`, not square brackets. You can construct a list with either square brackets or the `:` operator, but it's rarely a good idea to use both. – Robin Zigmond Feb 04 '19 at 15:26
  • 2
    You still need to indicate what the function should "return" if you *don't* get a list with 7 or more items, if you want to avoid the non-exhaustive pattern warning. That could be as simple as `take1and7 _ = error "List has too few elements"`. – chepner Feb 04 '19 at 15:39