
#10892: ApplicativeDo should use *> and <* -------------------------------------+------------------------------------- Reporter: simonmar | Owner: bollu Type: task | Status: new Priority: high | Milestone: 8.4.1 Component: Compiler | Version: 7.11 Resolution: | Keywords: ApplicativeDo Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: 12143 Related Tickets: #13309 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by AaronFriel): Yes, I was wondering about that too. Edward writes: "`(*>)` is typically a little cheaper than `(<*)`.", which suggests using the `*>` everywhere except in the tail, where we would use `<*`. Thus: {{{ do x <- foo bar y <- baz return ... ⇕ (\x y -> ...) <$> foo <*> (bar *> baz) }}} That is, we can merge any `ApplicativeArgNil lhsExpr` with a following `ApplicativeArg? rhsExpr`, by omitting the `ApplicativeArgNil` and creating a new `ApplicativeArg? rhsExpr'`, where `rhsExpr' = lhsExpr *> rhsExpr`. In cases where there is no subsequent statement, we use `<*`. This rewriting has the benefit of neatly addressing adding `liftA2`, as `ApplicativeArgNil` statements will be folded into `ApplicativeArgOne`/`ApplicativeArgMany`. e.g.: {{{ do foo x <- bar baz y <- quux quaffle return (xyzzy x y) ⇕ (\x y -> xyzzy x y) <$> (foo *> bar) <*> (baz *> quux) <* quaffle ⇕ liftAt (\x y -> xyzzy x y) (foo *> bar) (baz *> quux) <* quaffle }}} I'm working on the syntax and desugaring rules to address this and #13309. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10892#comment:23 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler