Let's say I want to make a special case for a function that matches strings that start with the character 'Z'. I could easily do it using pattern matching by doing something like the following:
myfunc ('Z' : restOfString) = -- do something special myfunc s = -- do the default case here
But what if I want to match strings with a longer prefix? Say I want to have a special case for strings that start with the word "toaster". What's the best way to write a pattern to match such a string?
Overview. We use pattern matching in Haskell to simplify our codes by identifying specific types of expression. We can also use if-else as an alternative to pattern matching. Pattern matching can also be seen as a kind of dynamic polymorphism where, based on the parameter list, different methods can be executed.
In a functional language, pattern matching involves checking an argument against different forms. A simple example involves recursively defined operations on lists. I will use OCaml to explain pattern matching since it's my functional language of choice, but the concepts are the same in F# and Haskell, AFAIK.
Pattern matching is a technique where you test an expression to determine if it has certain characteristics. C# pattern matching provides more concise syntax for testing expressions and taking action when an expression matches.
myfunc ('t':'o':'a':'s':'t':'e':'r' : restOfString) = ...
Using a normal pattern match works, but gets bothersome as the prefix string gets longer.
{-# LANGUAGE PatternGuards #-} import Data.List myFunc string | Just restOfString <- stripPrefix "toaster" string = -- do something special myFunc string = -- do the default case here
Using a library function instead of a pattern match is a bit easier to read and write.
{-# LANGUAGE ViewPatterns #-} import Data.List myFunc (stripPrefix "toaster" -> Just restOfString) = -- do something special myFunc string = -- do the default case here
A GHC 6.10 syntax extension makes this usage even more natural.
Of course, the latter two are completely equivalent, and we can make do (messily) without any sugar at all.
import Data.List myFunc string = if restIsJust then -- do something special else -- do the default case here where (restIsJust, restOfString) = case stripPrefix "toaster" string of Just something -> (True, something) Nothing -> (False, undefined)
Those syntax extensions are meant to make life easier for us, though.
import Data.List myFunc str | "toaster" `isPrefixOf` str = something restOfString | otherwise = somethingElse where Just restOfString = stripPrefix "toaster" str
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With