Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the function's name repeated when defining the function via pattern matching?

From Miran Lipovača's Learn you a Haskell for great good!:

lucky :: (Integral a) => a -> String  
lucky 7 = "LUCKY NUMBER SEVEN!"  
lucky x = "Sorry, you're out of luck, pal!"

In this definition of function lucky using pattern matching, why is the function's name repeated? When should I not be repeating the function's name? What is the meaning of it?

like image 790
Jas Avatar asked Jan 22 '26 15:01

Jas


2 Answers

This kind of pattern matching can be transformed to a case statement (and indeed, that's what compilers will normally do!):

lucky' n = case n of
    7 -> "LUCKY NUMBER SEVEN!"
    x -> "Sorry, you're out of luck, pal!"

Because the x isn't really used, you'd normally write _ -> "Sorry, ..." instead.

Note that this is not2 the same as

lucky'' n = if n==7 then ...

Equality comparison with (==) is in general more expensive1 than pattern matching, and also comes out uglier.


1 Why it's more expensive: suppose we have a big data structure. To determine that they are equal, the program will need to dig through both entire structures, make sure really all branches are equal. However, if you pattern match, you will just compare a small part you're interested in right now.

2 Actually, it is the same in the case, but just because the compiler has a particular trick for pattern matching on numbers: it rewrites it with (==). This is really special for Num types and not true for anything else. (Except if you use the OverloadedStrings extension.)

like image 55
leftaroundabout Avatar answered Jan 24 '26 09:01

leftaroundabout


What you are seeing is pattern match in action.

I will show you another example:

test 1 = "one"
test 2 = "two"
test 3 = "three"

Demo in ghci:

ghci> test 1
"one"
ghci> test 2
"two"
ghci> test 3
"three"
ghci> test 4
"*** Exception: Non-exhaustive patterns in function test

So, when you call any function, the runtime system will try to match the input with the defined function. So a call to test 3 will initially check test 1 and since 1 is not equal to 3, it will move on to the next definition. Again since 2 is not equal to 3, it will move to the next defintion. In the next definiton since 3 is equal to 3 it will return "three" String back. When you try to pattern match something, which doesn't exist at all, the program throws the exception.

like image 31
Sibi Avatar answered Jan 24 '26 08:01

Sibi