How to "split" an IO action in haskell
You can emulate this to some extent using Exception
s ,
{-# LANGUAGE DeriveDataTypeable #-}
import Control.Exception
import Data.Typeable
data MyException = MyException deriving (Show, Typeable)
instance Exception MyException
main = handle (\ MyException -> return ()) $ do
let a = 10 :: Int
print a
throwIO MyException
print $ a + 1 -- never gets executed
You can also do this with the ContT
or ErrorT
monad transformers , although they might be a little dishonest.
source to share
First, let me start with a warning that trying to translate imperative constructs into Haskell will likely lead to code that is not idiomatic, difficult to write, and difficult to read. Just because you can mimic some constructs using multiple monad transformers doesn't mean it really needs to be done.
That being said, here's an example of early return using Control.Monad.Cont.ContT
. The code below simulates an imperative return within multiple loops.
As Rufflewind warns , this can get cumbersome. Type callCC
one (not shown below) can be quite perplexing.
import Control.Monad.Cont
search :: Int -> IO (Maybe (Int,Int))
search x = runContT (callCC go) return
where go earlyReturn = do
forM_ [10..50] $ \i -> do
lift $ putStrLn $ "Trying i=" ++ show i
forM_ [10..50] $ \j -> do
lift $ putStrLn $ "Trying j=" ++ show j
when (i * j == x) $ do
lift $ putStrLn $ "Found " ++ show (i,j)
earlyReturn $ Just (i,j)
return Nothing
source to share