Below is some code coming from the answer to another stack overflow question. It's been several weeks i've started studying Haskell, and i had yet to encounter this particular syntax, and i can't find anywhere an explanation, not even a definition for it. So, the code:
data Pair a = P a a
instance Functor Pair where
fmap f (P x y) = P (f x) (f y)
instance Monad Pair where
return x = P x x
P a b >>= f = P x y
where P x _ = f a
P _ y = f b
I spent the last half-hour trying to understand the meaning of it, or if something i already knew explained the definition of this bind (>>=) method. GHCI loaded it without fretting (well it demanded an Applicative instance but other than that), so it must be very much allowed, even if i have yet to understand the beginning of it.
What is the meaning of what looks like a definition by pattern-matching of an already defined data constructor? What are x and y, where do they come from?
Thanks to anyone who answers to that. And if anyone has a good idea for a good, specific title to this question -- given I really don't understand the very syntaxic meaning, I have trouble finding one.
@leftaroundabout gave me the information I needed, which was that that bit of code
P x y
where P x _ = f a
P _ y = f b
was a form of pattern-matching of the "value-unboxing" type, instead of the case of
-like choice-oriented one. I was baffled by the presence of the _
pattern, and thus I didn't see the above two pattern-matchings as they were, that is, as the definitions of x
then y
, because it was done in a way I had never witnessed before.
I knew we could write something like that:
f :: foo -> (Int, Int)
...
i = let (a,b) = f x
in a + b
but I didn't know we could use, in these cases of "value-unboxing" (here a
and b
for example, or x
and y
in the code that bugged me), the full extent of the possibilities in pattern-matching, that is, at least, definitions using _
to isolate the parts we don't want, the values we don't want to bind to any "label".
In short I didn't know that in the above example, this equation
P x _ = f a
was actually the definition of x
through pattern-matching on the result of (f a)
, thus that it was strictly equivalent in effect to
x = g (f a)
where g (P t _) = t
I was stuck at thinking it was the definition of the already-defined data constructor P
.