exception, not in IO

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

exception, not in IO

Lyndon Maydwell
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?


On Sun, Jul 14, 2013 at 7:47 PM, Kees Bleijenberg <
k.bleijenberg at 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130714/8a48744b/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

exception, not in IO

Kees Bleijenberg
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 at 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 at haskell.org
http://www.haskell.org/mailman/listinfo/beginners

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130714/1b4f9561/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

exception, not in IO

Lyndon Maydwell
In reply to this post by 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. 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 at 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 at 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners****
>
> ** **
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130715/cdd00065/attachment.htm>

Reply | Threaded
Open this post in threaded view
|

exception, not in IO

Ertugrul Söylemez
Lyndon Maydwell <maydwell at gmail.com> wrote:

> 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130715/23e65944/attachment.pgp>

Reply | Threaded
Open this post in threaded view
|

exception, not in IO

Chaddaï Fouché
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
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?



Reply | Threaded
Open this post in threaded view
|

exception, not in IO

Kees Bleijenberg
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