エラー処理
Eitherを利用すると失敗の場合にも成功の場合にもデータ(Right)が付随する。
Bryan O'Sullivan,John Goerzen,Don Stewart
オライリージャパン / ¥ 3,990 ()
在庫あり。
tryとhandleも使える。
try :: IO a -> IO (Either Exception a)
handle :: (Exception e) => (e -> IO a) -> IO a -> IO a
19.3.1
import Control.Monad.Error
import Control.Monad.State
import qualified Data.ByteString.Char8 as B
data ParseError = NumericOverflow
| EndOfInput
| Chatty String
deriving (Eq, Ord, Show)
instance Error ParseError where
noMsg = Chatty "oh noes!"
strMsg = Chatty
newtype Parser a = P {
runP :: ErrorT ParseError (State B.ByteString) a
} deriving (Monad, MonadError ParseError)
liftP :: State B.ByteString a -> Parser a
liftP m = P (lift m)
satisfy :: (Char -> Bool) -> Parser Char
satisfy p = do
s <- liftP get
case B.uncons s of
Nothing -> throwError EndOfInput
Just (c, s')
| p c -> liftP (put s') >> return c
| otherwise -> throwError (Chatty "satisfy failed")
optional :: Parser a -> Parser (Maybe a)
optional p = (Just `liftM` p) `catchError` \_ -> return Nothing
runParser :: Parser a -> B.ByteString -> Either ParseError (a, B.ByteString)
runParser p bs = case runState (runErrorT (runP p)) bs of
(Left err, _) -> Left err
(Right r, bs) -> Right (r, bs)