Search code examples
haskellghcguard-clausepattern-guards

What does left arrow <- mean outside a do block?


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.


Solution

  • 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