Consider the following piece of code:
foo :: [Int]
foo = do
x <- [1..10]
if x < 5 then pure () else [] -- Control.Monad.guard (x < 5)
pure x
foo2 :: [Int]
foo2 =
[1..10] >>= \x ->
if x < 5 then pure x else [] >>= \y ->
pure y
In foo, I have manually inlined Control.Monad.guard (x < 5), as noted in the comment.
Why does foo compile, even though there is pure () in the code? How does the [()] pass the type check? Is it a special case for the do syntax? If yes, is it described anywhere?
In foo2, I attempted to "desugar" foo without the do syntax. Note that there can't be any pure (), as it doesn't pass type checking.
I'm using ghc-8.8.4 if that's important.