
Ertugrul, I don't understand all of it. This is what I've done {-# LANGUAGE OverloadedStrings,DeriveDataTypeable #-} module Test() where import Text.JSON import Text.JSON.Generic import Control.Exception import Control.Monad data Glass = Glass { a:: String, b:: String} deriving (Show,Typeable,Eq,Data,Read) data MyError = UnknownError deriving Show glassDecode :: String -> (Either MyError Glass) glassDecode s = Right ((decodeJSON s) :: Glass) glassEncode :: Glass -> Either MyError String glassEncode g = return $ encodeJSON g convert :: String -> Either MyError String convert = glassEncode <=< glassDecode test = convert "{\"a\":\"blah\",\"b\":\"blahb\"}" test2 = convert "{\"\":\"blah\",\"b\":\"blahb\"}" If I call test I get back Right <theInputString> If I call test2 (invalid string) I get Right "{*** Exception: fromJSON: field does not exist a" The good news is that the program doesn't halt any more. How do I transform the last Right to a Left (without changing the source in Text.JSON.Generic) if there is a error? The code in Text.JSON.Generic calls error "xxx" if something is wrong. Kees ..... IO is just one of the many monads with exception support. For your case, since JSON parsing is a pure process, you would want to use a pure exception monad like `Maybe` or `Either MyError`: data MyError = InvalidDateField | {- ... -} | UnknownError There is nothing wrong with using regular exception types, if you wish, in which case you might use `Either SomeException`. Then separate concerns: decode :: String -> Either MyError Glass encode :: Glass -> String Finally the conversion function is as simple as: convert :: String -> Either MyError String convert = fmap encode . decode If `encode` can fail as well and exceptions are regular Haskell exceptions: import Control.Exception import Control.Monad decode :: String -> Either SomeException Glass encode :: Glass -> Either SomeException String convert :: String -> Either SomeException String convert = encode <=< decode