簡體   English   中英

如何在哈斯克爾“打破”IO行動

[英]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

您也可以使用ContTErrorT 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM