簡體   English   中英

haskell當函數不返回IO monad時如何打印?

[英]haskell how to print when function doesn't return IO monad?

我基於它跟隨類型和monad:

data Err a = Ok a | Bad String
  deriving (Read, Show, Eq, Ord)

instance Monad Err where
  return      = Ok
  fail        = Bad
  Ok a  >>= f = f a
  Bad s >>= f = Bad s

instance Functor Err where
  fmap = liftM

我也有功能,它打印“asdf”屏幕並以錯誤結束(這是調試的臨時解決方案):

runStatments :: [Stm] -> State -> Err State
runStatments [] state = Ok state
runStatments (s:_) state = case s of
  PrintStmt exp -> do {
    e <- evalExpression exp state;
    k <- Ok $putStrLn "asfd";
    Bad "damn!"
  }
  ...

問題是代碼不會在屏幕上打印“asdf”...

什么是這種問題的溫和解決方案? 我試過了liftIO等等,但是我沒有編寫可編譯程序......

你不能只是將IO“堵塞”成monad,而不會在某些時候冒出來。 你需要做的是用所謂的monad變換器將Err monad包裹在IO monad周圍。

就像是

import Control.Monad
import Control.Monad.Trans

-- If you don't like `Either`, you can change it to
-- Err
data ErrT m a = ErrT {runErrT :: m (Either String a)}

instance (Monad m, Functor m) => Monad (ErrT m) where
  return = ErrT . return . Right
  (ErrT m) >>= f = ErrT $ do
      val <- m
      case val of
          Left err -> return  $ Left err
          Right a  -> runErrT $ f a

instance MonadTrans ErrT where
  lift = ErrT . liftM Right

然后你可以做這樣的事情

test :: ErrT IO ()
test = lift $ putStrLn "Hello World"

main = runErrT test

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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