[Haskell-beginners] exception, not in IO

Chaddaï Fouché chaddai.fouche at gmail.com
Mon Jul 15 17:39:47 CEST 2013

On Mon, Jul 15, 2013 at 1:47 PM, Ertugrul Söylemez <es at ertes.de> wrote:
>> 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

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.


More information about the Beginners mailing list