
I have read that Monad is stronger than Idiom because Monad lets me use the results of a computation to choose between the side effects of alternative future computations, while Idiom does not have this feature. Arrow does not have this feature either. ArrowChoice has the feature that the sum type, Either, can be used to choose between alternative computations, including their side effects. I know that Monad is supposed to be stronger than ArrowChoice, but I have to ask, what exactly can Monad do that ArrowChoice can't do? Let me set up an example to illustrate where I'm coming from.
import Control.Monad.Writer import Control.Applicative import Control.Arrow hiding (pure)
The missileControl function accepts a flag to determine whether missiles actually get launched, and it returns the number of casualties.
missileControl :: Bool -> IO Integer missileControl b = do showFlag b casualties <- if b then launchMissiles else doNotLaunch return casualties
showFlag :: Bool -> IO Bool showFlag b = (putStrLn $ "Launch flag = " ++ show b) >> return b
launchMissiles :: IO Integer launchMissiles = do putStrLn "Missiles have been launched." putStrLn "Casualties = 6,700,000,000." return 6700000000
doNotLaunch :: IO Integer doNotLaunch = putStrLn "Missiles not launched." >> return 0
If I try to use an Idiom, or even an Arrow, instead of a Monad, then I don't get to choose between the alternative side effects, and the results will be similar to this:
missileControl' :: Bool -> IO Integer missileControl' b = do showFlag b casualties <- launchMissiles casualties' <- doNotLaunch if b then return casualties else return casualties'
If I use ArrowChoice, then I can do this:
missileControl2 :: Bool -> IO Integer missileControl2 b = runKleisli a b where a = (Kleisli $ showFlag) >>> (arr boolToEither) >>> ((Kleisli $ const launchMissiles) ||| (Kleisli $ const doNotLaunch))
boolToEither :: Bool -> Either () () boolToEither True = Left () boolToEither False = Right ()
GHCi> missileControl2 True Launch flag = True Missiles have been launched. Casualties = 6,700,000,000. 6700000000 GHCi> missileControl2 False Launch flag = False Missiles not launched. 0

Ronald Guida wrote:
I have read that Monad is stronger than Idiom because Monad lets me use the results of a computation to choose between the side effects of alternative future computations, while Idiom does not have this feature. Arrow does not have this feature either.
ArrowChoice has the feature that the sum type, Either, can be used to choose between alternative computations, including their side effects. I know that Monad is supposed to be stronger than ArrowChoice, but I have to ask, what exactly can Monad do that ArrowChoice can't do?
Monads are equivalent to ArrowApply, they allow you to use a computed *action*. For example: getMissileLauncher :: IO (String -> IO ()) notWithArrows = do launchMissiles <- getMissleLauncher launchMissiles "Russia" ArrowChoice is not enough to implement this function. But it is possible with ArrowApply, of which Kleisli IO is an instance. Twan
participants (2)
-
Ronald Guida
-
Twan van Laarhoven