1

Consider the following function which runs a command:

getGrepStdout :: IO String
getGrepStdOut = do let cmd' = "grep"
                       pattern' = "//"
                       options' = "-nR"
                       path' = "/path/to/file"
                       stdin' = ""
                       args' = [pattern', options', path']
                   (_, stdout', _) <- readProcessWithExitCode cmd' args' stdin'
                   return stdout'

Notice the second to last line which has a double _ wild card matching (within a do block). This seems to compile fine in my case, but I was wondering if it was problematic formally speaking?

George
  • 6,927
  • 4
  • 34
  • 67
  • 2
    One way to think about it: It doesn't matter if you have two brothers named Darryl if you never need to refer to them. – ErikR May 14 '16 at 01:03

3 Answers3

4

No, there is no problem with having one or more _ in pattern matches, in do-blocks or otherwise. Why do you think there might be?

obadz
  • 889
  • 4
  • 10
  • 3
    Hypothesis for why it might be a problem. e.g. in python `_` isn't a wildcard, just a regular variable name that is used informally to indicate wildcard. – luqui May 14 '16 at 01:46
  • 1
    Well, you can do some simple pattern matching on the left side of `<-` (like `Just val <- someMaybeOperation`) , so one could assume that you're doing unification over `_` (like, what if you had `Pair x x <- operationGivingPair`?) – rtpg May 14 '16 at 01:50
2

You should be fine (at least with GHC).

It's good to be worried, because if you were to use any other identifier this would blow up!

Prelude> :{
Prelude| do
Prelude|     (x,x) <- return (1,1)
Prelude|     return x
Prelude| :}

<interactive>:12:6:
    Conflicting definitions for ‘x’
    Bound at: <interactive>:12:6
              <interactive>:12:8
    In a pattern binding in
         'do' block

The main thing is that this gets desugared to :

return (1,1) >>= \(x,x) -> return x

And lambda abstractions don't let you use the same local name twice. _ gets special treatment.


So for _, you're telling the compiler that you don't need whatever value's in there. And don't make any assumptions about the value.

In general you shouldn't be worrying about clobbering over your definitions in the same scope, Haskell won't really let you. Here's a related question about not being able to do things like :

plus a a = 2*a
plus a b = a + b

Which is actually pretty similar to this situation. _'s special treatment is needed.

Community
  • 1
  • 1
rtpg
  • 2,419
  • 1
  • 18
  • 31
  • `_` is **not** an identifier. If it were `f _ = _` would compile, while it doesn't. It's a wildcard. – Bakuriu May 14 '16 at 10:35
1

Strictly speaking, _ isn't really any more of a wildcard pattern than x or arg. What it is, however, is a hole. That means that it can not only accept any value, but won't bind that value to any particular variable. Since _ doesn't bind the value at all, using it twice in the same function declaration is perfectly valid, both theoretically and pragmatically.

Kwarrtz
  • 2,693
  • 15
  • 24