Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the order of function definition matter in list patterns

So these function orders have different behaviour in GHCI:

safetailpatter xs = tail xs
safetailpatter [] = []
safetailpatter [] = []
safetailpatter xs = tail xs

The former generates the following warning and the following error when passing in []

ex3.hs:66:1: warning: [-Woverlapping-patterns]
    Pattern match is redundant
    In an equation for ‘safetailpatter’: safetailpatter [] = ...
*** Exception: Prelude.tail: empty list

As such does the order of definition matter and why? I don't see why the former overlaps while the latter doesn't as the same definitions are given.

like image 599
Tarick Welling Avatar asked Apr 27 '20 14:04

Tarick Welling


People also ask

Does the order of the function definitions matter in Python?

So in general, yes, the order does matter; there's no hoisting of names in Python like there is in other languages (e.g JavaScript).

Does function order matter in PHP?

In normal php functions, it doesn't matter. You can use both of the types.

Does function order matter in C++?

Functions should at least be declared before being used. But once you declared them, the order does not matter (or very marginally).


Video Answer


2 Answers

xs also match the empty list, so safetailpatter [] will never be called if you place safetailpatter xs first.

I am pretty new to Haskell, but I think that is what is happening.

So, when you place safetailpatter xs first and then call it with an empty list, you are trying to call tail on the empty list, and you get the exception.

As for

Pattern match is redundant
    In an equation for ‘safetailpatter’: safetailpatter [] = ...

I think it means basically what I described above, it is complaining that the declaration is redundant because safetailpatter [] is already covered by safetailpatter xs when you put the latter one first.

That is the reason why you should always place _ at the end of your pattern matching definitions, other-way you the rest of the patterns will never get called:

myF (x:xs) = -- ....
myF _ = -- ...        -> Right
myF _ = -- ...        -> Wrong, now no the bellow definition will never get called
myF (x:xs) = -- ....
like image 77
Alejandro Alcalde Avatar answered Nov 15 '22 06:11

Alejandro Alcalde


Patterns are matched in order. But, what's going on here is that you are not actually parttern matching on safetailpatter xs.

In regular english safetailpatter xs = tail xs means: safetailpatter on any variable is tail of that variable.

What you want to match is: safetailpatter (x:xs) = tail (x:xs), which stands for: safetailpatter when applied on a list with at least one element, is tail of such a list

Knowing this, In the code

safetailpatter xs = tail xs
safetailpatter [] = []

Will check in order, and because the first equation matches any list input, you get a runtime error on []. Whereas

safetailpatter (x:xs) = tail xs
safetailpatter [] = []

matches in order, and since [] doesn't match the first equation, It'll run the second, with no runtime error

Edit

As @chepner says, this is call irrefutable pattern. Meaning that pattern matching is happening but there is no chance to fail. Same as if you match against _

like image 37
lsmor Avatar answered Nov 15 '22 04:11

lsmor