I came across with the following code recently and it bothers me a lot
lowerSafeForeignCall dflags block
| (entry, middle, CmmForeignCall { .. }) <- blockSplit block
= do
-- do block stuffs
-- Block doesn't end in a safe foreign call:
| otherwise = return block
This piece of code is from https://phabricator.haskell.org/rGHCb0534f78a73f972e279eed4447a5687bd6a8308e
in file compiler/cmm/CmmLayoutStack.hs
line 983
I really would like to konw what is this <- in the second line. I believe lowerSafeForeignCall is a function and the | and 'otherwise' indicate this function uses guards. So
(entry, middle, CmmForeignCall { .. }) <- blockSplit block
must be of type Bool. But the <- is outside any do block. I did some search online but still not a single clue about this usage.
That's a pattern guard:
guard → pat
<-
infixexp (pattern guard)
[...]
A guard has one of the following forms:
- pattern guards are of the form
p <- e
, where p is a pattern (see Section 3.17) of type t and e is an expression type t. They succeed if the expression e matches the pattern p, and introduce the bindings of the pattern to the environment.
Where normal guards are limited to a boolean check, pattern guards can match against an arbitrary pattern and define local variables. (In your case entry
, middle
, and the contents of CmmForeignCall
will be directly available in the function body.)
You can think of boolean guards as equivalent to pattern guards with a pattern of True
:
| expr
works like
| True <- expr