<|> that short-circuits in IO ?

Dear Haskell-Cafe, Is there a way to get Control.Applicative.<|> to short-circuit when combining two IO actions? E.g.
let a = putStrLn "A" >> return (Left "hehe") let b = putStrLn "B" >> return (Right 42)
Prelude> liftA2 (<|>) a b
A B Right 42
liftA2 (<|>) b a
B A Right 42 (In the latter case I don't want A in the output…) Many thanks for your help, Semen -- Семен Тригубенко http://trygub.com

On 30/10/14 15:42, Semen Trygubenko / Семен Тригубенко wrote:
Dear Haskell-Cafe,
Is there a way to get Control.Applicative.<|> to short-circuit when combining two IO actions?
E.g.
let a = putStrLn "A" >> return (Left "hehe") let b = putStrLn "B" >> return (Right 42)
Prelude> liftA2 (<|>) a b
A B Right 42
liftA2 (<|>) b a
B A Right 42
(In the latter case I don't want A in the output…)
Wrap it into ExceptT (from the latest transformers), as in runExceptT $ ExceptT a <|> ExceptT b Roman

On Thu, Oct 30, 2014 at 8:50 PM, Roman Cheplyaka
liftA2 (<|>) b a
B A Right 42
(In the latter case I don't want A in the output…)
Wrap it into ExceptT (from the latest transformers), as in
runExceptT $ ExceptT a <|> ExceptT b
With the latest transformers, I still get B A Right 42 i.e. the A hasn't been eliminated. What am I missing? -- Kim-Ee

On Sat, Nov 01, 2014 at 04:22:28AM +0700, Kim-Ee Yeoh wrote:
On Thu, Oct 30, 2014 at 8:50 PM, Roman Cheplyaka
wrote: liftA2 (<|>) b a
B A Right 42
(In the latter case I don't want A in the output…)
Wrap it into ExceptT (from the latest transformers), as in
runExceptT $ ExceptT a <|> ExceptT b
With the latest transformers, I still get
B A Right 42
i.e. the A hasn't been eliminated.
What am I missing?
In the actual use case ErrorT was already wrapping IO and that's what I was combining with <|>, so, for now, lacking the latest transformers, I have written a custom infix operator. I haven't had a chance to test Roman's solution and assumed it to be correct. So your observation is a valuable "data point" — thank you! Apologies, I should have tested this myself sooner, S. -- Семен Тригубенко http://trygub.com

With the latest transformers, I still get
B A Right 42
i.e. the A hasn't been eliminated.
What am I missing?
Can you show us your code? Looking at the source: http://hackage.haskell.org/package/transformers-0.4.1.0/docs/src/Control-Mon... http://hackage.haskell.org/package/transformers-0.4.1.0/docs/src/Control-Mon... both ExceptT and ErrorT have short-circuiting <|> and mplus. Chris

On 31/10/14 23:22, Kim-Ee Yeoh wrote:
On Thu, Oct 30, 2014 at 8:50 PM, Roman Cheplyaka
wrote: liftA2 (<|>) b a
B A Right 42
(In the latter case I don't want A in the output…)
Wrap it into ExceptT (from the latest transformers), as in
runExceptT $ ExceptT a <|> ExceptT b
With the latest transformers, I still get
B A Right 42
i.e. the A hasn't been eliminated.
What am I missing?
I don't know what you're missing, but when I run the following code, it doesn't print A. import Control.Monad.Except import Control.Applicative a = putStrLn "A" >> return (Left "hehe") b = putStrLn "B" >> return (Right 42) main = runExceptT $ ExceptT b <|> ExceptT a Roman

Chris, thank you for the links. I now understand ExceptT a lot better. Roman, thank you for the full program. What happened was I copy-pasted runExceptT $ ExceptT a <|> ExceptT b from your email into ghci. But you said the latest transformers was required, so I did the install. Finally, I saw an "A" printed out and went "Hey, that's not right!" Returning to the mail client, I referred back to Semen's original query and copy-pasted from there. But really it was A then B that I saw and not B then A. So mea culpa. Truth be told, all that while I was figuring out how to get Semen's "liftA2 (<|>)" to work and suffered cognitively from the lazy I/O solution I pursued. -- Kim-Ee
participants (4)
-
Chris Wong
-
Kim-Ee Yeoh
-
Roman Cheplyaka
-
Semen Trygubenko / Семен Тригубен ко