From Scala to Haskell
for comprehension
// given:
// maybeInt: Option[Int] = ???

res: Option[(Int, Int, Int)] = for {
    a <- maybeInt
    b <- maybeInt
    c <- maybeInt
} yield (a, b, c)
-- given:
-- maybeInt :: Maybe Int

res :: Maybe (Int, Int, Int)
res = do a <- maybeInt
         b <- maybeInt
         c <- maybeInt
         return (a, b, c)

return is not a keyword - it's just a function of type Monad m => a -> m a so you can think of it as pure in cats or monix.

This form of do notation is whitespace-sensitive. Subsequent terms (a, b, c in the example above) must be aligned horizontally.