
I agree that it seems uncomfortable for a seemingly pure function to require handling exceptions in the IO monad, but if the code in question really does have the capability of raising IO exceptions, then I think it is reasonable to consider it as impure and belonging in the IO monad and that it probably should not have been given a pure type signature to start with. 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... Other than that, I guess we'd need a snippet of the code and what libraries are being used in order to provide better help. Good luck! On Mon, Jul 15, 2013 at 4:07 AM, Kees Bleijenberg < k.bleijenberg@lijbrandt.nl> wrote:
Lyndon,****
You wrote: You can turn anything into an IO action with return, or you could catch the exception at a level where you are performing IO. Would this be what you're after?****
Wait until you perform IO, seems quit uneasy to me and why? Converting a string to a typeable is not a IO action. Problem is that this function lives in a dll. The IO is done by the calling program (not a Haskell program). The function is not in a monad, it is a pure function. So I think I can’t do a return.****
Kees****
On Sun, Jul 14, 2013 at 7:47 PM, Kees Bleijenberg < k.bleijenberg@lijbrandt.nl> wrote:****
The app I’am working on, converts a jsonString to another string encoding. ****
The function I want to write is jsonString -> (encoding, errorMsg) so String-> (String, String) ****
For this purpose I have a typeable datastructure Glass. Because it is typeable I can do (decodeJSON jsonString) :: Glass****
But sometimes the jsonString is not valid (misformed or wrong fields). decodeJSON then throws a exception. I want to****
catch that exection and transform the result to something like (“” , theErrorMsg). Unfortunately all catch functions want IO parameters. ****
What can I do?****
****
Kees****
****
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners****
** **
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Lyndon Maydwell
I agree that it seems uncomfortable for a seemingly pure function to require handling exceptions in the IO monad, but if the code in question really does have the capability of raising IO exceptions, then I think it is reasonable to consider it as impure and belonging in the IO monad and that it probably should not have been given a pure type signature to start with.
No, pure computations can throw Haskell exceptions just fine, and the exceptions can be caught and handled without IO. Using Either SomeException instead of IO is the recommended way to do it.
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. There is a natural transformation from Either SomeException to IO: liftEither :: (Exception e) => Either e a -> IO a liftEither = either throwIO return Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.

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ï

Jedaï ...... 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 : 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. --- This is a nice solution for the problem. Thanks! Kees
participants (4)
-
Chaddaï Fouché
-
Ertugrul Söylemez
-
Kees Bleijenberg
-
Lyndon Maydwell