Reputation: 939
In the source code for the Applicative instance for Maybe we have:
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
Just _m1 *> m2 = m2
Nothing *> _m2 = Nothing
I had thought that '_' is used as a wildcard in patterns. What is the meaning here therefore of '_m' and '_m2' values? Is this a GHC coding convention? Is there some performance advantage to not using _?
Upvotes: 4
Views: 2343
Reputation: 36622
You're right that _
is a wildcard. What you see here are just variables with names beginning with _
; there's no special syntax. Both _
and variables match any value, but _
signals that you're ignoring that value. Consequently, GHC will warn you if you define a variable and don't use it, which comes in handy. But what if you want to document what you're ignoring, without being warned that you're ignoring it? Well, _
is just another word character in Haskell, so you can begin a variable name with it. And GHC will assume that any _
-initial variable names you defined are intended to be unused, and refrain from warning you about them.
Thus, in
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
The _m
is used to be clear that it's the same thing as the m
above, but isn't being used. If we replaced it with _
, that might be less clear. And if we replaced it with m
, we'd get a warning:
…: warning: [-Wunused-matches]
Defined but not used: ‘m’
In general, _
is only a little bit special in Haskell pattern matches. Besides the "no warnings" property above (which doesn't change what the program does, only the compiler messages), matching against _
is almost exactly like matching against any other variable. There are only two differences:
You can match against multiple _
s at once.
star1, star2 :: a -> b -> Char
star1 _ _ = '*'
star2 x y = '*'
-- ILLEGAL:
-- star3 x x = '*'
Every _
is distinct – two underscores are not the same thing as each other. However, when we match against variables, all the variables we match against have to be distinct; you can't match against "x" twice. (You can sort of think of _
as a variable whose name is different each time.)
You can't use _
in expressions, only in patterns.
id2 :: a -> a
-- ILLEGAL:
-- id1 _ = _
id2 x = x
Because _
doesn't "remember" what it matched against, as we saw above, you can never use it in an expression. It's only ever a pattern.
Upvotes: 3
Reputation: 48654
If you don't use the _
prefix, you will get warning when compiling:
gcc -Wall test.hs:
test.hs:21:18: Warning: Defined but not used: ‘m’
test.hs:23:11: Warning: Defined but not used: ‘m1’
test.hs:24:18: Warning: Defined but not used: ‘m2’
You can use _
to avoid the warnings. So, _var
is used to give a name to the variable and to avoid warning. You can do something like this:
Justa m1 *> _m = _m
But with wildcards, you cannot do something like this:
Just m1 *> _ = _
Upvotes: 1