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