9

I have a problem with a function that should only return the tail of a list. The functions is myTail and should give a useable result, even if the input is an empty list.

I want to understand all 3 ways: pattern matching, guarded equation and conditional expressions

this works:

> myTail_pat :: [a] -> [a]

> myTail_pat (x:xs) = xs
> myTail_pat [] = []

But this:

> myTail_guard (x:xs)   | null xs = []
>               | otherwise = xs

gives me the error: Program error: pattern match failure: myTail_guard [] How can i declare the function without patterns?

Thank you.

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
Tarion
  • 16,283
  • 13
  • 71
  • 107

2 Answers2

17

The pattern x:xs does not match the empty list. You'd need to do:

myTail_guard xs
  | null xs   = []
  | otherwise = tail xs
Chuck
  • 234,037
  • 30
  • 302
  • 389
13

drop 1 is safe

drop 1 []
-- result: []
Ilya Kharlamov
  • 3,698
  • 1
  • 31
  • 33
  • Is there any negative effects to using this approach vs the normal tail function or pattern match? – Lightbulb1 Apr 09 '18 at 20:41
  • @Lightbulb1 please define what is a "negative effect", is that a side effect or what. The only difference between "tail" and "drop 1" is that tail throws an error on an empty list. – Ilya Kharlamov Apr 09 '18 at 21:08
  • Thanks for your response. I was thinking in terms of performance. – Lightbulb1 Apr 09 '18 at 22:06
  • 1
    Although I believe it's implemented using a linked list so the performance is the same, you must not have the implementation performance under consideration when writing a program in Haskell. In a more philosophic way, in an imperative language you tell the compiler "how to do it" and in a functional one you tell "what you want to get done". If performance is your priority, then rather take ASM or C golang or something similar. – Ilya Kharlamov Apr 10 '18 at 21:40