The article is kind of overcomplicating things in favor of really trying preserve `forever`.
Here's an easy one with `whileM` (the one parameter version that is effectively a do-while loop, where the while condition is the expression's return value, there is a two parameter version that takes an independent boolean parameter).
main :: IO ()
main = do
wsUrl <- fetchConnectionUrl
conn <- connectWebSocket wsUrl
whileM $ do
message <- readMessage conn
case message of
MessageA val -> putStrLn "Message A" $> True
MessageB val -> putStrLn "Message B" $> True
Disconnect -> pure False
EDIT: ah I read a little too quickly. The author wants to have arbitrary breaks in the while loop. In that case you can use https://hackage.haskell.org/package/loop-while-1.0.0/docs/Co... which is morally the same thing without the `mzero` jargon (which really is just a generalized `break` here). The other alternative is to just stick with whileM and just normal structured programming if-else blocks that eventually end up returning true or false.