Reputation: 3076
I want to have the "return" (in imperative language) function in haskell.
E.g.
main = do
let a = 10
print a
-- return this function
print $ a + 1
How can I achieve this?
Upvotes: 3
Views: 712
Reputation: 116174
First, let me start by warning that trying to translate imperative constructs into Haskell will likely lead to code which is not idiomatic, hard to write, and hard to read. Just because you can simulate some constructs by using a few monad transformers, it does not mean that this should actually be done.
That being said, here's an example of early return using Control.Monad.Cont.ContT
. The code below simulates an imperative return inside a few for loops.
As Rufflewind warns, this can get unwieldy. The type of callCC
alone (not shown below) can be quite puzzling.
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
Upvotes: 2
Reputation: 8966
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 it with the ContT
or ErrorT
monad transformers, although they can a bit unwieldly.
Upvotes: 2