In a nutshell, patterns are like defining piecewise functions in math. You can specify different function bodies for different arguments using patterns. When you call a function, the appropriate body is chosen by comparing the actual arguments with the various argument patterns.
Read A Gentle Introduction to Haskell for more information.
In a nutshell, patterns are like defining piecewise functions in math. You can specify different function bodies for different arguments using patterns. When you call a function, the appropriate body is chosen by comparing the actual arguments with the various argument patterns.
Read A Gentle Introduction to Haskell for more information. Compare: with the equivalent Haskell: fib 0 = 1 fib 1 = 1 fib n | n >= 2 = fib (n-1) + fib (n-2) Note the "n? 2" in the piecewise function becomes a guard in the Haskell version, but the other two conditions are simply patterns.
Patterns are conditions that test values and structure, such as x:xs, (x, y, z), or Just x. In a piecewise definition, conditions based on = or? Relations (basically, the conditions that say something "is" something else) become patterns.
Guards allow for more general conditions. We could rewrite fib to use guards: fib n | n == 0 = 1 | n == 1 = 1 | n >= 2 = fib (n-1) + fib (n-2).
Pattern matching is, at least in Haskell, deeply tied to the concept of algebraic data types. When you declare a data type like this: data SomeData = Foo Int Int | Bar String | Baz ...it defines Foo, Bar, and Baz as constructors--not to be confused with "constructors" in OOP--that construct a SomeData value out of other values. Pattern matching is nothing more than doing this in reverse--a pattern would "deconstruct" a SomeData value into its constituent pieces (in fact, I believe that pattern matching is the only way to extract values in Haskell).
When there are multiple constructors for a type, you write multiple versions of a function for each pattern, with the correct one being selected depending on which constructor was used (assuming you've written patterns to match all possible constructions--which it's generally good practice to do).
1 The "multiple version of a function" are really just syntax sugar for a case statement: learnhaskell.blogspot.com/2007/09/lesson... – Jared Updike Feb 9 '10 at 1:28.
There are other good answers, so I'm going to give you a very technical answer. Pattern matching is the elimination construct for algebraic data types: "Elimination construct" means "how to consume or use a value" "Algebraic data type", in addition to first-class functions, is the big idea in a statically typed functional language like Clean, F#, Haskell, or ML The idea of algebraic data types is that you define a type of thing, and you say all the ways you can make that thing. As an example, let's define "Sequence of String" as an algebraic data type, with three ways to make it: data StringSeq = Empty -- the empty sequence | Cat StringSeq StringSeq -- two sequences in succession | Single String -- a sequence holding a single element Now, there are all sorts of things wrong with this definition, but as an example it's interesting because it provides constant-time concatenation of sequences of arbitrary length.(There are other ways to achieve this.
) The declaration introduces Empty, Cat, and Single, which are all the ways there are of making sequences. (That makes each one an introduction construct—a way to make things.) You can make an empty sequence without any other values. To make a sequence with Cat, you need two other sequences.
To make a sequence with Single, you need an element (in this case a string) Here comes the punch line: the elimination construct, pattern matching, gives you a way to scrutinize a sequence and ask it the question what constructor were you made with?. Because you have to be prepared for any answer, you provide at least one alternative for each constructor. Here's a length function: slen :: StringSeq -> Int slen s = case s of Empty -> 0 Cat s s' -> slen s + slen s' Single _ -> 1 At the core of the language, all pattern matching is built on this case construct.
However, because algebraic data types and pattern matching are so important to the idioms of the language, there's special "syntactic sugar" for doing pattern matching in the declaration form of a function definition: slen Empty = 0 slen (Cat s s') = slen s + slen s' slen (Single _) = 1 With this syntactic sugar, computation by pattern matching looks a lot like definition by equations.(The Haskell committee did this on purpose. ) And as you can see in the other answers, it is possible to specialize either an equation or an alternative in a case expression by slapping a guard on it. I can't think of a plausible guard for the sequence example, and there are plenty of examples in the other answers, so I'll leave it there.
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.
Here is the definition of a function to compute the length of a list lst. In OCaml, an `a list is defined recursively as the empty list , or the structure h::t, where h is an element of type a (a being any type we want, such as an integer or even another list), t is a list (hence the recursive definition), and :: is the cons operator, which creates a new list out of an element and a list. So the function would look like this: let rec len lst = match lst with -> 0 | h :: t -> 1 + len t rec is a modifier that tells OCaml that a function will call itself recursively.
Don't worry about that part. The match statement is what we're focusing on. OCaml will check lst against the two patterns - empty list, or h :: t - and return a different value based on that.
Since we know every list will match one of these patterns, we can rest assured that our function will return safely. Note that even though these two patterns will take care of all lists, you aren't limited to them. A pattern like h1 :: h2 :: t (matching all lists of length 2 or more) is also valid.
Of course, the use of patterns isn't restricted to recursively defined data structures, or recursive functions. Here is a (contrived) function to tell you whether a number is 1 or 2: let is_one_or_two num = match num with 1 -> true | 2 -> true | _ -> false In this case, the forms of our pattern are the numbers themselves. _ is a special catch-all used as a default case, in case none of the above patterns match.
Pattern matching is one of those painful operations that is hard to get one's head around if you come from procedural programming background. I find it hard to get into because the same syntax used to create a data structure can be used for matching. In F# you can use the cons operator :: to add an element to the beginning of a list like so: let a = 1 :: 2;3 //val a : int list = 1; 2; 3 Similarly you can use the same operator to split the list up like so: let a = 1;2;3;; match a with | a;b -> printfn "List contains 2 elements" //will match a list with 2 elements | a::tail -> printfn "Head is %d" a //will match a list with 2 or more elements | -> printfn "List is empty" //will match an empty list.
1 "... the same syntax used to create a data structure can be used for matching" - that's pretty much the point; you use pattern matching to find out which constructor was used to make a value - see Norman Ramsey's or camccann's answers. It also helps to realise that cons is not merely a function that acts on lists (like length or concatenate), but is a list constructor. Of course, as the Fibonacci examples show, you can pattern match on specific values such as 0 or 1 as well as constructors such as cons or Just (a common one from Haskell).
– Nefrubyr Feb 9 '10 at 12:01.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.