
On Mon, Jul 15, 2013 at 1:47 PM, Ertugrul Söylemez
I'd double check to see if the function in question has the capability of raising an exception in a more pure monad as per Kees's suggestion. The other option is to perform the actions I've suggested and then wrap the whole lot in unsafePerformIO to make it pure again but with a new signature of (a -> Either YourException b), however that just makes me feel even more queazy...
That's about the worst solution you could consider. It's not a valid use case for unsafePerformIO. You can just use Either right away. I don't understand why you insist on IO and use hazardously unsafe constructs to satisfy the insistence.
I think there's a point you didn't catch on : the decode function is provided as is by a library and isn't written by the original poster, if that calls error, the decode function can't be sanely used in a pure solution to catch incorrect input, except by some monstrosity as proposed by some (I think the spoon library encapsulated this horror neatly). Of course, there's a thing that haven't been considered, the source code is available, so let's look at this function : -- |Decode a string as a value. decodeJSON :: (Data a) => String -> a decodeJSON s = case runGetJSON readJSValue s of Left msg -> error msg Right j -> case fromJSON j of Error msg -> error msg Ok x -> x We discover that this function is pretty simple in fact and combine some pure code that does provide pure exceptions, so defining a new function may bring a solution : -- |Decode a string as a value. tryDecodingJSON :: (Data a) => String -> Result a tryDecodingJSON s = case runGetJSON readJSValue s of Left msg -> Error msg Right j -> fromJSON j You may need to import Text.JSON.String for runGetJSON. -- Jedaï