Monadic function fails as Nothing in Maybe context but as Exception in Either context.

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

Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Jeffrey Brown
I've written a monadic function which in a Maybe context produces a Nothing when it fails (as intended), but in an Either context produces an Exception rather than a Left.

Here's a tiny demonstration. "tinyGraph" below has one Node, 0, with the label "dog". If I try to change the label at Node 0 to "cat", it works. If I try to change the label at Node 1 to "cat", it fails, because Node 1 is not in the graph.

    type MyGraph = Gr String String

    tinyGraph = mkGraph [(0, "dog")] [] :: MyGraph

    maybeSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Maybe MyGraph
      -- == Just (mkGraph [(0,"cat")] [])
    maybeFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Maybe MyGraph
      -- == Nothing

    eitherSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Either String MyGraph
      -- ==  Right (mkGraph [(0,"cat")] [])
    eitherFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Either String MyGraph
      -- *** Exception: Node not in Graph

Here's the code:

    import Data.Graph.Inductive -- FGL, the Functional Graph Library

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                  -- True if the node is in the graph
      else fail "Node not in Graph"   -- False otherwise

    replaceStringAtNode :: MyGraph -> Node -> String -> MyGraph
    replaceStringAtNode g n e = let (Just (a,b,c,d),g') = match n g
      in (a,b,e,d) & g'

    replaceStringAtNodeM :: (Monad m) => MyGraph -> Node -> String -> m MyGraph
    replaceStringAtNodeM g n s = do
      gelemM g n
      return $ replaceStringAtNode g n s
        -- if evaluated, the pattern match in replaceStringAtNode must succeed,
        -- because gelemM catches the case where n is not in the graph



--
Jeffrey Benjamin Brown

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Oleg Grenrus
Hi, Jeffrey

in short: `fail` of `Either e` throws an exception (i.e. is not overriden, default implementation is `fail s = error s`) [1, 2]

For `Maybe`, fail is defined as `fail _ = Nothing`; which is good default. [3] 

You probably want to use for example `throwError from `mtl` package [4]:

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                        -- True if the node is in the graph
      else throwError "Node not in Graph"   -- False otherwise


- Oleg

On 01 Dec 2015, at 00:25, Jeffrey Brown <[hidden email]> wrote:

I've written a monadic function which in a Maybe context produces a Nothing when it fails (as intended), but in an Either context produces an Exception rather than a Left.

Here's a tiny demonstration. "tinyGraph" below has one Node, 0, with the label "dog". If I try to change the label at Node 0 to "cat", it works. If I try to change the label at Node 1 to "cat", it fails, because Node 1 is not in the graph.

    type MyGraph = Gr String String

    tinyGraph = mkGraph [(0, "dog")] [] :: MyGraph

    maybeSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Maybe MyGraph
      -- == Just (mkGraph [(0,"cat")] [])
    maybeFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Maybe MyGraph
      -- == Nothing

    eitherSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Either String MyGraph
      -- ==  Right (mkGraph [(0,"cat")] [])
    eitherFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Either String MyGraph
      -- *** Exception: Node not in Graph

Here's the code:

    import Data.Graph.Inductive -- FGL, the Functional Graph Library

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                  -- True if the node is in the graph
      else fail "Node not in Graph"   -- False otherwise

    replaceStringAtNode :: MyGraph -> Node -> String -> MyGraph
    replaceStringAtNode g n e = let (Just (a,b,c,d),g') = match n g
      in (a,b,e,d) & g'

    replaceStringAtNodeM :: (Monad m) => MyGraph -> Node -> String -> m MyGraph
    replaceStringAtNodeM g n s = do
      gelemM g n
      return $ replaceStringAtNode g n s
        -- if evaluated, the pattern match in replaceStringAtNode must succeed,
        -- because gelemM catches the case where n is not in the graph



--
Jeffrey Benjamin Brown
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Michael Walker
In reply to this post by Jeffrey Brown
On Mon, 30 Nov 2015 14:25:49 -0800
Jeffrey Brown <[hidden email]> wrote:

> I've written a monadic function which in a Maybe context produces a
> Nothing when it fails (as intended), but in an Either context
> produces an Exception rather than a Left.

The Monad instance for (Either e) uses the default definition of 'fail',
which is to throw an exception:

instance Monad (Either e) where
    return = Right
    Left  l >>= _ = Left l
    Right r >>= k = k r

In general, 'Left' can't be used because that would only type check
for (Either String), but the Monad instance is more general than that.

--
Michael Walker (http://www.barrucadu.co.uk)
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Oleg Grenrus
In reply to this post by Oleg Grenrus

On 01 Dec 2015, at 00:34, Oleg Grenrus <[hidden email]> wrote:

Hi, Jeffrey

in short: `fail` of `Either e` throws an exception (i.e. is not overriden, default implementation is `fail s = error s`) [1, 2]

For `Maybe`, fail is defined as `fail _ = Nothing`; which is good default. [3] 

You probably want to use for example `throwError from `mtl` package [4]:


I haven’t still tested it, but less wrong context is `MonadError String m`:

    gelemM :: (MonadError String m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                        -- True if the node is in the graph
      else throwError "Node not in Graph"   -- False otherwise


- Oleg

On 01 Dec 2015, at 00:25, Jeffrey Brown <[hidden email]> wrote:

I've written a monadic function which in a Maybe context produces a Nothing when it fails (as intended), but in an Either context produces an Exception rather than a Left.

Here's a tiny demonstration. "tinyGraph" below has one Node, 0, with the label "dog". If I try to change the label at Node 0 to "cat", it works. If I try to change the label at Node 1 to "cat", it fails, because Node 1 is not in the graph.

    type MyGraph = Gr String String

    tinyGraph = mkGraph [(0, "dog")] [] :: MyGraph

    maybeSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Maybe MyGraph
      -- == Just (mkGraph [(0,"cat")] [])
    maybeFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Maybe MyGraph
      -- == Nothing

    eitherSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Either String MyGraph
      -- ==  Right (mkGraph [(0,"cat")] [])
    eitherFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Either String MyGraph
      -- *** Exception: Node not in Graph

Here's the code:

    import Data.Graph.Inductive -- FGL, the Functional Graph Library

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                  -- True if the node is in the graph
      else fail "Node not in Graph"   -- False otherwise

    replaceStringAtNode :: MyGraph -> Node -> String -> MyGraph
    replaceStringAtNode g n e = let (Just (a,b,c,d),g') = match n g
      in (a,b,e,d) & g'

    replaceStringAtNodeM :: (Monad m) => MyGraph -> Node -> String -> m MyGraph
    replaceStringAtNodeM g n s = do
      gelemM g n
      return $ replaceStringAtNode g n s
        -- if evaluated, the pattern match in replaceStringAtNode must succeed,
        -- because gelemM catches the case where n is not in the graph



--
Jeffrey Benjamin Brown
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Bryan Richter-2
In reply to this post by Jeffrey Brown
On Mon, Nov 30, 2015 at 02:25:49PM -0800, Jeffrey Brown wrote:
> I've written a monadic function which in a Maybe context produces a Nothing
> when it fails (as intended), but in an Either context produces an Exception
> rather than a Left.

The Maybe instance for Monad overrides fail to be Nothing, but Either
instance does not. The default definition for fail is error.

The Except type has the behavior you are looking for, I believe — but
you may be better off avoiding the use of fail to begin with. :)

Except/ExceptT:
http://haddock.stackage.org/lts-3.16/transformers-0.4.2.0/Control-Monad-Trans-Except.html

Also recommended for all your error-ful needs:
http://haddock.stackage.org/lts-3.16/errors-2.0.1/Control-Error.html


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Jeffrey Brown
In reply to this post by Oleg Grenrus
Oleg's suggestion works! I just had to add these two lines in order to use it:

    {-# LANGUAGE FlexibleContexts #-}
    import Control.Monad.Except -- mtl library

Thanks, everybody!

On Mon, Nov 30, 2015 at 2:38 PM, Oleg Grenrus <[hidden email]> wrote:

On 01 Dec 2015, at 00:34, Oleg Grenrus <[hidden email]> wrote:

Hi, Jeffrey

in short: `fail` of `Either e` throws an exception (i.e. is not overriden, default implementation is `fail s = error s`) [1, 2]

For `Maybe`, fail is defined as `fail _ = Nothing`; which is good default. [3] 

You probably want to use for example `throwError from `mtl` package [4]:


I haven’t still tested it, but less wrong context is `MonadError String m`:

    gelemM :: (MonadError String m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                        -- True if the node is in the graph
      else throwError "Node not in Graph"   -- False otherwise


- Oleg

On 01 Dec 2015, at 00:25, Jeffrey Brown <[hidden email]> wrote:

I've written a monadic function which in a Maybe context produces a Nothing when it fails (as intended), but in an Either context produces an Exception rather than a Left.

Here's a tiny demonstration. "tinyGraph" below has one Node, 0, with the label "dog". If I try to change the label at Node 0 to "cat", it works. If I try to change the label at Node 1 to "cat", it fails, because Node 1 is not in the graph.

    type MyGraph = Gr String String

    tinyGraph = mkGraph [(0, "dog")] [] :: MyGraph

    maybeSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Maybe MyGraph
      -- == Just (mkGraph [(0,"cat")] [])
    maybeFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Maybe MyGraph
      -- == Nothing

    eitherSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Either String MyGraph
      -- ==  Right (mkGraph [(0,"cat")] [])
    eitherFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Either String MyGraph
      -- *** Exception: Node not in Graph

Here's the code:

    import Data.Graph.Inductive -- FGL, the Functional Graph Library

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                  -- True if the node is in the graph
      else fail "Node not in Graph"   -- False otherwise

    replaceStringAtNode :: MyGraph -> Node -> String -> MyGraph
    replaceStringAtNode g n e = let (Just (a,b,c,d),g') = match n g
      in (a,b,e,d) & g'

    replaceStringAtNodeM :: (Monad m) => MyGraph -> Node -> String -> m MyGraph
    replaceStringAtNodeM g n s = do
      gelemM g n
      return $ replaceStringAtNode g n s
        -- if evaluated, the pattern match in replaceStringAtNode must succeed,
        -- because gelemM catches the case where n is not in the graph



--
Jeffrey Benjamin Brown
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe




--
Jeffrey Benjamin Brown

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Jeffrey Brown
I spoke too soon; I'm seeing the same problem with MonadError.

    Prelude> :set -XFlexibleContexts
    Prelude> import Control.Monad.Except
    Prelude Control.Monad.Except> let f = (fail "be Left!" :: (MonadError String m) => m ())
    Loading package transformers-0.4.2.0 ... linking ... done.
    Loading package mtl-2.2.1 ... linking ... done.
    Prelude Control.Monad.Except> f :: Either String ()
    *** Exception: be Left!
    Prelude Control.Monad.Except> 



On Mon, Nov 30, 2015 at 6:18 PM, Jeffrey Brown <[hidden email]> wrote:
Oleg's suggestion works! I just had to add these two lines in order to use it:

    {-# LANGUAGE FlexibleContexts #-}
    import Control.Monad.Except -- mtl library

Thanks, everybody!

On Mon, Nov 30, 2015 at 2:38 PM, Oleg Grenrus <[hidden email]> wrote:

On 01 Dec 2015, at 00:34, Oleg Grenrus <[hidden email]> wrote:

Hi, Jeffrey

in short: `fail` of `Either e` throws an exception (i.e. is not overriden, default implementation is `fail s = error s`) [1, 2]

For `Maybe`, fail is defined as `fail _ = Nothing`; which is good default. [3] 

You probably want to use for example `throwError from `mtl` package [4]:


I haven’t still tested it, but less wrong context is `MonadError String m`:

    gelemM :: (MonadError String m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                        -- True if the node is in the graph
      else throwError "Node not in Graph"   -- False otherwise


- Oleg

On 01 Dec 2015, at 00:25, Jeffrey Brown <[hidden email]> wrote:

I've written a monadic function which in a Maybe context produces a Nothing when it fails (as intended), but in an Either context produces an Exception rather than a Left.

Here's a tiny demonstration. "tinyGraph" below has one Node, 0, with the label "dog". If I try to change the label at Node 0 to "cat", it works. If I try to change the label at Node 1 to "cat", it fails, because Node 1 is not in the graph.

    type MyGraph = Gr String String

    tinyGraph = mkGraph [(0, "dog")] [] :: MyGraph

    maybeSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Maybe MyGraph
      -- == Just (mkGraph [(0,"cat")] [])
    maybeFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Maybe MyGraph
      -- == Nothing

    eitherSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Either String MyGraph
      -- ==  Right (mkGraph [(0,"cat")] [])
    eitherFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Either String MyGraph
      -- *** Exception: Node not in Graph

Here's the code:

    import Data.Graph.Inductive -- FGL, the Functional Graph Library

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                  -- True if the node is in the graph
      else fail "Node not in Graph"   -- False otherwise

    replaceStringAtNode :: MyGraph -> Node -> String -> MyGraph
    replaceStringAtNode g n e = let (Just (a,b,c,d),g') = match n g
      in (a,b,e,d) & g'

    replaceStringAtNodeM :: (Monad m) => MyGraph -> Node -> String -> m MyGraph
    replaceStringAtNodeM g n s = do
      gelemM g n
      return $ replaceStringAtNode g n s
        -- if evaluated, the pattern match in replaceStringAtNode must succeed,
        -- because gelemM catches the case where n is not in the graph



--
Jeffrey Benjamin Brown
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe




--
Jeffrey Benjamin Brown



--
Jeffrey Benjamin Brown

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Oleg Grenrus
Use `throwError`, not `fail`. :)

Forget `fail`. Luckily we are taking it out of `Monad`.

- Oleg

On 01 Dec 2015, at 20:44, Jeffrey Brown <[hidden email]> wrote:

I spoke too soon; I'm seeing the same problem with MonadError.

    Prelude> :set -XFlexibleContexts
    Prelude> import Control.Monad.Except
    Prelude Control.Monad.Except> let f = (fail "be Left!" :: (MonadError String m) => m ())
    Loading package transformers-0.4.2.0 ... linking ... done.
    Loading package mtl-2.2.1 ... linking ... done.
    Prelude Control.Monad.Except> f :: Either String ()
    *** Exception: be Left!
    Prelude Control.Monad.Except> 



On Mon, Nov 30, 2015 at 6:18 PM, Jeffrey Brown <[hidden email]> wrote:
Oleg's suggestion works! I just had to add these two lines in order to use it:

    {-# LANGUAGE FlexibleContexts #-}
    import Control.Monad.Except -- mtl library

Thanks, everybody!

On Mon, Nov 30, 2015 at 2:38 PM, Oleg Grenrus <[hidden email]> wrote:

On 01 Dec 2015, at 00:34, Oleg Grenrus <[hidden email]> wrote:

Hi, Jeffrey

in short: `fail` of `Either e` throws an exception (i.e. is not overriden, default implementation is `fail s = error s`) [1, 2]

For `Maybe`, fail is defined as `fail _ = Nothing`; which is good default. [3] 

You probably want to use for example `throwError from `mtl` package [4]:


I haven’t still tested it, but less wrong context is `MonadError String m`:

    gelemM :: (MonadError String m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                        -- True if the node is in the graph
      else throwError "Node not in Graph"   -- False otherwise


- Oleg

On 01 Dec 2015, at 00:25, Jeffrey Brown <[hidden email]> wrote:

I've written a monadic function which in a Maybe context produces a Nothing when it fails (as intended), but in an Either context produces an Exception rather than a Left.

Here's a tiny demonstration. "tinyGraph" below has one Node, 0, with the label "dog". If I try to change the label at Node 0 to "cat", it works. If I try to change the label at Node 1 to "cat", it fails, because Node 1 is not in the graph.

    type MyGraph = Gr String String

    tinyGraph = mkGraph [(0, "dog")] [] :: MyGraph

    maybeSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Maybe MyGraph
      -- == Just (mkGraph [(0,"cat")] [])
    maybeFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Maybe MyGraph
      -- == Nothing

    eitherSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Either String MyGraph
      -- ==  Right (mkGraph [(0,"cat")] [])
    eitherFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Either String MyGraph
      -- *** Exception: Node not in Graph

Here's the code:

    import Data.Graph.Inductive -- FGL, the Functional Graph Library

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                  -- True if the node is in the graph
      else fail "Node not in Graph"   -- False otherwise

    replaceStringAtNode :: MyGraph -> Node -> String -> MyGraph
    replaceStringAtNode g n e = let (Just (a,b,c,d),g') = match n g
      in (a,b,e,d) & g'

    replaceStringAtNodeM :: (Monad m) => MyGraph -> Node -> String -> m MyGraph
    replaceStringAtNodeM g n s = do
      gelemM g n
      return $ replaceStringAtNode g n s
        -- if evaluated, the pattern match in replaceStringAtNode must succeed,
        -- because gelemM catches the case where n is not in the graph



--
Jeffrey Benjamin Brown
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe




--
Jeffrey Benjamin Brown



--
Jeffrey Benjamin Brown


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Jeffrey Brown
Right! That's what I was doing when I got it to work and then I forgot. I will correct the habit. Sorry for the annoyance!

On Tue, Dec 1, 2015 at 10:46 AM, Oleg Grenrus <[hidden email]> wrote:
Use `throwError`, not `fail`. :)

Forget `fail`. Luckily we are taking it out of `Monad`.

- Oleg


On 01 Dec 2015, at 20:44, Jeffrey Brown <[hidden email]> wrote:

I spoke too soon; I'm seeing the same problem with MonadError.

    Prelude> :set -XFlexibleContexts
    Prelude> import Control.Monad.Except
    Prelude Control.Monad.Except> let f = (fail "be Left!" :: (MonadError String m) => m ())
    Loading package transformers-0.4.2.0 ... linking ... done.
    Loading package mtl-2.2.1 ... linking ... done.
    Prelude Control.Monad.Except> f :: Either String ()
    *** Exception: be Left!
    Prelude Control.Monad.Except> 



On Mon, Nov 30, 2015 at 6:18 PM, Jeffrey Brown <[hidden email]> wrote:
Oleg's suggestion works! I just had to add these two lines in order to use it:

    {-# LANGUAGE FlexibleContexts #-}
    import Control.Monad.Except -- mtl library

Thanks, everybody!

On Mon, Nov 30, 2015 at 2:38 PM, Oleg Grenrus <[hidden email]> wrote:

On 01 Dec 2015, at 00:34, Oleg Grenrus <[hidden email]> wrote:

Hi, Jeffrey

in short: `fail` of `Either e` throws an exception (i.e. is not overriden, default implementation is `fail s = error s`) [1, 2]

For `Maybe`, fail is defined as `fail _ = Nothing`; which is good default. [3] 

You probably want to use for example `throwError from `mtl` package [4]:


I haven’t still tested it, but less wrong context is `MonadError String m`:

    gelemM :: (MonadError String m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                        -- True if the node is in the graph
      else throwError "Node not in Graph"   -- False otherwise


- Oleg

On 01 Dec 2015, at 00:25, Jeffrey Brown <[hidden email]> wrote:

I've written a monadic function which in a Maybe context produces a Nothing when it fails (as intended), but in an Either context produces an Exception rather than a Left.

Here's a tiny demonstration. "tinyGraph" below has one Node, 0, with the label "dog". If I try to change the label at Node 0 to "cat", it works. If I try to change the label at Node 1 to "cat", it fails, because Node 1 is not in the graph.

    type MyGraph = Gr String String

    tinyGraph = mkGraph [(0, "dog")] [] :: MyGraph

    maybeSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Maybe MyGraph
      -- == Just (mkGraph [(0,"cat")] [])
    maybeFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Maybe MyGraph
      -- == Nothing

    eitherSucceed = replaceStringAtNodeM tinyGraph 0 "cat" :: Either String MyGraph
      -- ==  Right (mkGraph [(0,"cat")] [])
    eitherFail = replaceStringAtNodeM tinyGraph 1 "cat" :: Either String MyGraph
      -- *** Exception: Node not in Graph

Here's the code:

    import Data.Graph.Inductive -- FGL, the Functional Graph Library

    gelemM :: (Monad m) => MyGraph -> Node -> m ()
    gelemM g n = if gelem n g       -- FGL's gelem function returns
      then return ()                  -- True if the node is in the graph
      else fail "Node not in Graph"   -- False otherwise

    replaceStringAtNode :: MyGraph -> Node -> String -> MyGraph
    replaceStringAtNode g n e = let (Just (a,b,c,d),g') = match n g
      in (a,b,e,d) & g'

    replaceStringAtNodeM :: (Monad m) => MyGraph -> Node -> String -> m MyGraph
    replaceStringAtNodeM g n s = do
      gelemM g n
      return $ replaceStringAtNode g n s
        -- if evaluated, the pattern match in replaceStringAtNode must succeed,
        -- because gelemM catches the case where n is not in the graph



--
Jeffrey Benjamin Brown
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe




--
Jeffrey Benjamin Brown



--
Jeffrey Benjamin Brown




--
Jeffrey Benjamin Brown

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Will Yager
In reply to this post by Jeffrey Brown
Shouldn't that be "throwError", not "fail"?

--Will

On Tue, Dec 1, 2015 at 12:44 PM, Jeffrey Brown <[hidden email]> wrote:
I spoke too soon; I'm seeing the same problem with MonadError.

    Prelude> :set -XFlexibleContexts
    Prelude> import Control.Monad.Except
    Prelude Control.Monad.Except> let f = (fail "be Left!" :: (MonadError String m) => m ())
    Loading package transformers-0.4.2.0 ... linking ... done.
    Loading package mtl-2.2.1 ... linking ... done.
    Prelude Control.Monad.Except> f :: Either String ()
    *** Exception: be Left!
    Prelude Control.Monad.Except> 



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Monadic function fails as Nothing in Maybe context but as Exception in Either context.

Will Yager
Oops, disregard that. Other responses didn't show up for some reason.

On Tue, Dec 1, 2015 at 2:34 PM, William Yager <[hidden email]> wrote:
Shouldn't that be "throwError", not "fail"?

--Will

On Tue, Dec 1, 2015 at 12:44 PM, Jeffrey Brown <[hidden email]> wrote:
I spoke too soon; I'm seeing the same problem with MonadError.

    Prelude> :set -XFlexibleContexts
    Prelude> import Control.Monad.Except
    Prelude Control.Monad.Except> let f = (fail "be Left!" :: (MonadError String m) => m ())
    Loading package transformers-0.4.2.0 ... linking ... done.
    Loading package mtl-2.2.1 ... linking ... done.
    Prelude Control.Monad.Except> f :: Either String ()
    *** Exception: be Left!
    Prelude Control.Monad.Except> 




_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe