How to "split" an IO action in haskell

I want to have a return function (in imperative language) in haskell.

eg.

main = do
  let a = 10
  print a
--  return this function
  print $ a + 1

      

How can I achieve this?

+3


source to share


2 answers


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.

+2


source


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

      

+2


source







All Articles