views:

102

answers:

2

Lets say i have a piece of code like this:

test pattern
 | pattern == (_,NOT (WIRE _)) = 1     
 | pattern == (_,AND (WIRE _) (WIRE _)) = 2
 | otherwise = 0

Where i am trying to match it against one of several possibilities, some with one (WIRE ""), some with two. I have actual input as follows e.g.: ("p",NOT (WIRE "x")). I would like to have a pattern that could accept any letter as input (what i was hoping for with the _) and am failing dismally (illegal _). Is it possible to do this in haskell?

A: 

Why do you need guards for this? Am I missing something? Below is the legal Haskell code I think you're looking for.

test (_,NOT (WIRE _)) = 1     
test (_,AND (WIRE _) (WIRE _)) = 2
test _ = 0
TomMD
Belated thanks...
commentator8
+5  A: 

OK, this makes a lot more sense after the edit.

== compares values, but _ is a pattern. Patterns appear in only the following syntactic contexts:

  • on the left hand side of a (pattern) binding, i.e. "what's before =", at top level or in where blocks or in let expressions or commands (in do notation);
  • to the left of <- in do notation or in a list comprehension;
  • to the left of -> in a case expression;
  • as the formal arguments of functions, either in function bindings or lambda (\) expressions.

(I hope I haven't forgotten any!) In your case, you can achieve what you want by simply writing

test (_, NOT (WIRE _)) = 1
test (_, AND (WIRE _) (WIRE _)) = 2
test _ = 0

You might ask what is the correct version of "pattern == (_, NOT (WIRE _))". Well, you can write:

case pattern of
  (_, NOT (WIRE _)) -> True
  _ -> False
Reid Barton
Thanks for that, it clears things up somewhat. Being haskell there is still a while till i feel completely comfortable with it though...
commentator8
Great answer... educational as well as solutional. :-)
LarsH
I think it's also worth pointing out the reverse: in pattern matching, all the identifiers are patterns and not values. So `NOT` and `WIRE` need to be data constructors or (string or numeric) literals for that to work. In this case it works, since they're upper case. People learning Haskell often trip over this at some point. For example, you can't test against constants by pattern matching - `f someNum = error "not that one!"` is not at all the same as `f x | x == someNum = error "not that one!"`.
mokus