Looking for more information about Pattern Matching

Hi, I am very much a newbie to Haskell and currently working through http://learnyouahaskell.com and trying some of the http://www.haskell.org/haskellwiki/99_questions. I am struggling to get my head around pattern matching. I think I can understand the individual patterns presented in LYAH, but can't seem to find any information about generalising the formats. Is there a good resource that describes the patterns that are available or provides more details about how to create them. For example the format of [x] and (x:xs) seem very different and I cant quite get a handle on the syntax(?) behind them. I can see how patterns work when shown an example, but wouldn't know how to create one from scratch. I hope you can understand what I am trying to say - its a little difficult to explain. Thanks Graham

On Apr 28, 2011, at 5:35 PM, Graham Hopper wrote:
Hi,
I am very much a newbie to Haskell and currently working through http://learnyouahaskell.com and trying some of the http://www.haskell.org/haskellwiki/99_questions. I am struggling to get my head around pattern matching. I think I can understand the individual patterns presented in LYAH, but can't seem to find any information about generalising the formats.
Is there a good resource that describes the patterns that are available or provides more details about how to create them.
For example the format of [x] and (x:xs) seem very different and I cant quite get a handle on the syntax(?) behind them. I can see how patterns work when shown an example, but wouldn't know how to create one from scratch.
I hope you can understand what I am trying to say - its a little difficult to explain.
[x] means a list with one element (x:xs) means give me the head as x and the rest as xs, you only know there is at least one element. What is happening is Haskell is using the type constructor to create and deconstruct the value for you. Look also at the example of 'tell' in LYAH's Pattern Matching with Lists and List Comprehensions. He uses (x:[]) as a synonym for [x]. (I put this in sample.hs) foo [x] = "Just " ++ show x foo (x:xs) = "Head " ++ show x ++ foo xs foo [] = "" bar (Just x) = show x bar Nothing = "Nothing" data Example = Ex1 Int | Ex2 String deriving (Show) examplePlay (Ex1 n) = "An Int " ++ show n examplePlay (Ex2 s) = "A String " ++ show s anotherExample = let e = Ex1 5 in putStrLn $ examplePlay e $ ghci Prelude> :load sample [1 of 1] Compiling Main ( sample.hs, interpreted ) Ok, modules loaded: Main. *Main> foo [1..10] "Head 1Head 2Head 3Head 4Head 5Head 6Head 7Head 8Head 9Just 10" *Main> foo [1] "Just 1" *Main> foo [] "" *Main> bar $ Just 5 "5" *Main> bar $ Just [1..10] "[1,2,3,4,5,6,7,8,9,10]" *Main> bar Nothing "Nothing" *Main> examplePlay (Ex1 5) "An Int 5" *Main> examplePlay (Ex2 "Foo") "A String \"Foo\"" *Main> anotherExample An Int 5

On Friday 29 April 2011 02:35:13, Graham Hopper wrote:
Hi,
I am very much a newbie to Haskell and currently working through http://learnyouahaskell.com and trying some of the http://www.haskell.org/haskellwiki/99_questions. I am struggling to get my head around pattern matching. I think I can understand the individual patterns presented in LYAH, but can't seem to find any information about generalising the formats.
Is there a good resource that describes the patterns that are available or provides more details about how to create them.
For example the format of [x] and (x:xs) seem very different and I cant quite get a handle on the syntax(?) behind them.
The second is an ordinary constructor-application-pattern, the first is not a true pattern, it's syntax sugar for lists. Basically, a pattern is - a wildcard, '_' - a variable pattern, var these two match everything, a wildcard does no binding, a variable pattern binds the matched value to the name and makes it available for use (on the rhs of the definition, after the '->' in a case expression, ...) Or - a constructor application, (Con arg1 arg2), (x:xs), (a,b,c,d), ((:) x xs) the constructor has to be saturated, so if it takes n arguments to construct a value of type t, it has to be supplied with n arguments in a pattern-match. These arguments are themselves patterns (variable patterns in the example), so patterns can be nested (to arbitrary depth, where arbitrary means limited by the available memory). Also there are - as-patterns, var@(a1:a2:rest), which matches against the detailed pattern and binds the entire value to var and the components to the corresponding names in the as-pattern - lazy patterns, ~(x:xs), which do no matching immediately and only try to match and bind when a component is demanded (that can lead to run-time errors if e.g. the value is in fact an empty list). Then there are some special cases which are not really patterns but quasi- patterns, supplied for convenience: - number literals, 0, 1, 1.245, ... foo 1 = bar is in fact foo n | n == 1 = bar - record patterns, Con{ field = value }, Con{ field1 = value1, field2 = value2 } those are shorthand for (Con _ _ value _ _) etc. with the appropriate number of wildcards and the value-pattern in the correct place One can use the special form of no supplied values, Con{}, even for datatypes declared without record-syntax. - special forms of list patterns, "string", [a,b], which are desugared to ('s':'t':'r':'i':'n':'g':[]) resp. (a:b:[]) - tuple patterns, (a,b), (a,b,c,d,e) these are strictly ((,) a b), ((,,,,) a b c d e)
I can see how patterns work when shown an example, but wouldn't know how to create one from scratch.
I hope you can understand what I am trying to say - its a little difficult to explain.
Thanks
Graham

On Fri, 29 Apr 2011 03:27:48 +0200
Daniel Fischer
On Friday 29 April 2011 02:35:13, Graham Hopper wrote: Basically, a pattern is [...] Or
- a constructor application, (Con arg1 arg2), (x:xs), (a,b,c,d), ((:) x xs) [...] Also there are [...]
I've been wondering about this case. Since : is "just another
function", then if things were consistent, I ought to be able to use
other functions in constructor applications. But my attempts to do so
always seem to result in syntax errors.
So my question is - what are the rules for constructor applications?
Is the list above complete? Are there just a few more? Is there some
rule to determine which functions are ok in patterns and which aren't?
Thanks,

On Friday 29 April 2011 18:43:51, Mike Meyer wrote:
On Fri, 29 Apr 2011 03:27:48 +0200
Daniel Fischer
wrote: On Friday 29 April 2011 02:35:13, Graham Hopper wrote: Basically, a pattern is
[...]
Or
- a constructor application, (Con arg1 arg2), (x:xs), (a,b,c,d), ((:) x xs)
[...]
Also there are
[...]
I've been wondering about this case. Since : is "just another function",
It's "just another function" in the same sense as Just or Right are "just another function". They all are (non-nullary) constructors. They are "just another function" in the sense that they take arguments and produce values, and you can pass them to any higher order function like every other function (that is, if the type matches) or have them as results of other functions. They are however special functions in the sense that, as they are constructors, you can pattern-match on them (fully applied, you can't do foo :: (Char -> Either Char Int) -> Bool foo Left = True foo _ = False ).
then if things were consistent, I ought to be able to use other functions in constructor applications. But my attempts to do so always seem to result in syntax errors.
So my question is - what are the rules for constructor applications? Is the list above complete?
I think this time I haven't forgotten anything, but don't be too sure, better check the report.
Are there just a few more? Is there some rule to determine which functions are ok in patterns and which aren't?
You can match on constructor applications, nothing else, except for the few special cases, - number literals (sugar for an equality test) - character literals ('a' is not really a constructor, matching on character literals also gives rise to an equality test) - string literals ("foo") - list patterns ([x1,x2,x3]) Special syntax for convenience, reduces to ('f' : 'o' : 'o' : []) resp. (x1 : x2 : x3 : []). - tuples are constructor applications, but with special (wired-in) syntax, so those patterns don't match the normal cases of Con pat1 pat2 ... patN -- prefix constructor application pat1 :$%& pat2 -- infix constructor application - labelled patterns, Con{ field1 = pat1, ..., fieldN = patN } (N >= 0) You can tell constructors apart from "ordinary functions" by case, if the name begins with an upper-case letter, it's a constructor, if it begins with a lower-case letter or an underscore, it's an "ordinary function". For operators, the rule is the same if you regard ':' as an upper-case- symbol (and the only one); an infix operator is a constructor if and only if it starts with ':'. So, (x : xs), infix application of the operator (:), : obviously starts with ':', hence a constructor ~> valid pattern. (x && y); infix application of the operator (&&), && doesn't start with ':', no constructor ~> not a valid pattern.
Thanks,
participants (4)
-
Daniel Fischer
-
Graham Hopper
-
Mike Meyer
-
Sean Perry