我想在haskell中使用“返回”(使用命令式语言)功能。
E.g。
main = do
let a = 10
print a
-- return this function
print $ a + 1
我怎样才能做到这一点?
答案 0 :(得分:2)
您可以使用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
你也可以使用ContT
or ErrorT
monad transformers来完成它,虽然它们可能有点笨拙。
答案 1 :(得分:2)
首先,让我首先警告说,尝试将命令式构造转换为Haskell可能会导致代码不是惯用的,难以编写且难以阅读。仅仅因为你可以通过使用一些monad变换器来模拟一些构造,这并不意味着实际上应该这样做。
话虽如此,这是使用Control.Monad.Cont.ContT
提前返回的一个例子。下面的代码模拟了几个for循环中的命令性返回。
正如Rufflewind警告的那样,这可能会变得笨拙。单独callCC
的类型(下面未显示)可能非常令人费解。
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