1

I have a guard and the condition is that lookup x list == something i.e. x is in the list. I tried:

| lookup x list == _ = my code here

But when loading the function I get a "pattern syntax in expression context" error?

James
  • 161
  • 1
  • 8

2 Answers2

1

You'd use a guard like

| any ((x ==) . fst) list = ... code ...

The specific error message you get is because _ is not a valid identifier. The token _ is only valid in pattern matches, and pattern matches can only be used in places that explicitly allow them. Patterns are never an expression, so they can't be used any place that expects an arbitrary expression.

If you enable the PatternGuards extension in GHC, you could also do what you want with syntax like:

| Just _ <- lookup x list = ... code ...

Note that I'm matching on Just results, rather than all results. Remember that lookup still produces a value when it doesn't find something, and that the _ pattern matches all values.

Noting that pattern guard syntax works out to be the same amount of typing here, the advantage to using it in this case is that it also lets you bind a name to the value looked up, if you so desire.

| Just y <- lookup x list = ... code that uses y...

Doing this without pattern guards would require a pattern match inside the body, which would possibly be a bit unsatisfying.

Carl
  • 26,500
  • 4
  • 65
  • 86
  • 1
    It is not illegal to have pattern matching in a guard (just stick a `case…of` in there.) However, the comparison operator `(==)` expects two bools, not a bool and a pattern. – kqr Nov 22 '13 at 16:23
  • @kqr Hmm, I worded that slightly badly. Fixing. – Carl Nov 22 '13 at 16:25
  • Whoops, I just realized my answer was wrong anyway. Fixed now. – Carl Nov 22 '13 at 16:27
  • No I don't like . notation what is: | any ((x ==) . fst) list = ... code ... without the . ? – James Nov 22 '13 at 16:39
  • @James `(x ==) . fst` is the same thing as `\t -> x == fst t`. – kqr Nov 22 '13 at 16:41
  • 2
    @James The `.` operator in Haskell is something you should learn about. There's a reason it's a single character infix operator - it is powerful and useful. It allows you to compose two functions together into a new function with minimal syntactic overhead - an important building block for languages that are about combining small single-purpose functions into the logic you need. – Carl Nov 22 '13 at 16:45
  • Okay but just for reference how would you write the function the same way without a . ? – James Nov 22 '13 at 17:02
  • @Carl Can you recommend any good guides on the . (how do I make it look like code in comments?) operator? – James Nov 22 '13 at 17:34
  • @James I can only tell you how I learned about it.. I spent a bunch of time in the #haskell irc channel on freenode, asking beginner questions, and paying attention to answers to other questions. Sooner or later, I just absorbed it. I don't know if there's any way to get used to it other than practice. – Carl Nov 23 '13 at 20:13
1

Or if you find you want to leave the gratuitous pattern-matching hidden in a library...

import Data.Maybe (fromJust)

...
    | isJust (lookup x list) = ...
Aaron Roth
  • 456
  • 2
  • 5