[英]How to “break” IO action in haskell
我想在haskell中使用“返回”(使用命令式語言)功能。
例如
main = do
let a = 10
print a
-- return this function
print $ a + 1
我怎樣才能做到這一點?
你可以在某種程度上使用Exception
來模擬這個,
{-# 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
或ErrorT
monad變換器來完成它,盡管它們可能有點笨拙。
首先,讓我首先警告說,嘗試將命令式構造轉換為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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.