Is pattern matching really that different from switch statements, which are really just fancy if statements?
Trying not to sound sarcastic, but if people are for if-free programming, pattern matching does not seem to be the answer for me. When I add a new type in haskell, I usually find myself having to look through all my pattern matchings.
Is pattern matching really that different from switch statements, which are really just fancy of statements?
Mostly, yes. Pattern matching also provides destructuring, allowing you to bind constructor arguments and pattern match against such arguments as well. For instance:
fun (Just (x:_)) = ...
But some of the downsides are comparable to switch statements, e.g. if you modify:
data MyType = Foo | Bar
to
data MyType = Foo | Bar | Baz
You will have to (potentially) update all functions or case expressions to account for Baz. One could use parametric polymorphism, comparably to the linked article, to make more extensible code. In such a case, one would define a type class such as:
class (Show a) => Printer p where
printIt :: p -> a -> IO ()
And one could make particular printers of this typeclass. You could even throw in existential quantification so that a function does not specialize to a particular Printer.
Pattern matching is a lot more expressive that switch and if statements, as it combines testing with elimination. For instance, let's say we want to write a new tail function, which returns the tail of a list but returns [] when the list is empty (pseudo-Haskell):
tail2 xs = case xs of { Nil => []; Cons(x,xs) => xs }
tail2' xs = if xs == Nil then [] else tail xs
In the second case, tail2', the compiler won't stop us if we switch the two branches. In the first case, tail2, we only get access to the tail of the list if the list is actually non-empty.
In essence, the difference is that if statements throws away any static information about the test result, whereas pattern matching constructs lets that information flow to each branch through variable binding.
I second the question, pattern matching is cool for destructuring or for completeness checking (not sure those are fundamental properties of pattern matching though), but it does not solve the problem of adding new behaviour without changing existing code any more than an `if` does.
Trying not to sound sarcastic, but if people are for if-free programming, pattern matching does not seem to be the answer for me. When I add a new type in haskell, I usually find myself having to look through all my pattern matchings.