Newbie Q: Monad 'fail' and 'error'

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

Newbie Q: Monad 'fail' and 'error'

dokondr
Monad class contains declaration

fail :: String -> m a

and provides default implementation for 'fail' as:

fail s = error s

On the other hand Prelude defines:

error
:: String -> a

which stops execution and displays an error message.

Questions:
1) What value and type 'error' actually returns in:
error "some message" ?

2) How declaration
String -> m a
matches with
String -> a ?

3) In Maybe monad:
fail = Nothing

When and how 'fail' is used in Maybe monad?

Thanks!

--
Dmitri O. Kondratiev
[hidden email]
http://www.geocities.com/dkondr
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Newbie Q: Monad 'fail' and 'error'

Ilya Tsindlekht
On Wed, Jun 06, 2007 at 01:39:32PM +0400, Dmitri O.Kondratiev wrote:

> Monad class contains declaration
>
> *fail* :: String -> m a
>
> and provides default implementation for 'fail' as:
>
> fail s = error s
>
> On the other hand Prelude defines:
> *
> error* :: String -> a
>
> which stops execution and displays an error message.
>
> Questions:
> 1) What value and type 'error' actually returns in:
> error "some message" ?
'a' here is a type variable, therefore 'error' is a polymorphic function
which can return value of any type.
>
> 2) How declaration
> String -> m a
> matches with
> String -> a ?
as I said above, 'String->a' means that the return value can have any type.
'String-> m a' means that return value may be of type 'm a' where 'a'
can be any type.
>
> 3) In Maybe monad:
> fail = Nothing
'Nothing' is constructor which returns value of type 'Maybe a' where 'a'
is any type.
>
> When and how 'fail' is used in Maybe monad?
Values of type 'Maybe a' can be either 'Just x' where x is value of type
'a' or 'Nothing'. The Maybe monad is used to represent computations
which may fail, 'Just x' represents successful computation yielding
value x, and 'Nothing' represents failing computation.
>
> Thanks!
>
> --
> Dmitri O. Kondratiev
> [hidden email]
> http://www.geocities.com/dkondr

> _______________________________________________
> Haskell-Cafe mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/haskell-cafe

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

Re: Newbie Q: Monad 'fail' and 'error'

Tillmann Rendel
In reply to this post by dokondr
Dmitri O.Kondratiev wrote:

> Monad class contains declaration
>
> *fail* :: String -> m a
>
> and provides default implementation for 'fail' as:
>
> fail s = error s
>
> On the other hand Prelude defines:
> *
> error* :: String -> a
>
> which stops execution and displays an error message.
>
> Questions:
> 1) What value and type 'error' actually returns in:
> error "some message" ?

For practical purposes:

   typechecking: every type the context asks for.
   execution: no value, because execution stops.

For theoretical purposes, error could be implemented by

   error :: String -> a
   error msg = error msg

with the extra-semantical magical side effect of printing msg and
aborting execution.

> 2) How declaration
> String -> m a
> matches with
> String -> a ?

Alpha renaming to fresh variables yields

   String -> b c
   String -> d

wich unifies by taking d := b c.

> 3) In Maybe monad:
> fail = Nothing
>
> When and how 'fail' is used in Maybe monad?

The default fail implementation is not very clever. If something fails,
execution is aborted and the user is confronted with some error message.
Some monads support richer error handling schemes. The maybe monad
encodes a succeeding computation with Just it's result, and a failed
computation with Nothing.

An example:

-- divBy is a possible failing computation in some monad
divBy :: Monad m => Int -> Int -> m Int
divBy a 0 = fail "div by zero"
divBy a b = return (a `div` b)

-- div by three succeeds
15 `divBy` 3 :: Maybe Int   ~~>   Just 5

-- div by zero fails
15 `divBy` 0 :: Maybe Int   ~~>   Nothing

-- divByAll is a shortcut for a list of divBy's
divByAll :: Monad m => Int -> [Int] -> [m Int]
divByAll a bs = map (divBy a) bs

-- div by all returns a list of computations
15 `divByAll` [3, 0] :: [Maybe Int]   ~~>   [Just 5, Nothing]

-- sequence succeeds if all computations in a list succeeds
sequence (15 `divByAll` [3, 0]) :: Maybe [Int]   ~~>   Nothing
sequence (15 `divByAll` [3, 5]) :: Maybe [Int]   ~~>   Just [5, 3]

divBy, divByAll, sequence do not know anything about Maybe, they work
for all monads, because they only use >>=, fail and return.

The idea is that Monad defines some general interface for computations,
and the various Monad instances define the exact behaviour. Maybe's
behaviour is: if a subcomputation fails, the whole computation fails.

There are other monads. consider the list monad, and it's behaviour: if
a subcomputation fails, backtrack and try some other alternative.

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

Re: Newbie Q: Monad 'fail' and 'error'

Mark T.B. Carroll-2
In reply to this post by dokondr
"Dmitri O.Kondratiev" <[hidden email]> writes:
(snip)
> 1) What value and type 'error' actually returns in:
> error "some message" ?

For the purpose of type checking, error returns whatever value is
expected for that expression by whatever is 'using' the value. In
practice, 'error' terminates programme execution so that it evades the
trouble of figuring out how to construct a return value of the correct
type.

> 2) How declaration
> String -> m a
> matches with
> String -> a ?

'a' can be any type, including 'm a'. (Those are different 'a's! So
I should really rename 'm a' to 'm b' when I use them in the same
sentence.)

> 3) In Maybe monad:
> fail = Nothing
>
> When and how 'fail' is used in Maybe monad?

A common way to think of the Maybe monad is that it represents a thing
that works only if all the parts worked. If any of the parts (bound with
>>=) fail, then the Nothing is contagious across bind, as the >>=
doesn't have a value to feed in to the next function as its argument,
and the return value of the whole thing is Nothing.

-- Mark

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

Re: Newbie Q: Monad 'fail' and 'error'

dokondr
In reply to this post by Tillmann Rendel
Thanks for excellent explanation!  Examples really help.

So, in general  'fail' behavior will differ from monad to monad.
In this example:

divBy :: Monad m => Int -> Int -> m Int
divBy a 0 = fail "div by zero"
divBy a b = return (a `div` b)

Default 'fail' implementation in Monad class will be:
*DivBy> divBy 5 0
Loading package haskell98-1.0 ... linking ... done.
*** Exception: user error (div by zero)

And when explicitly defining monad as Maybe it will be different:
*DivBy> divBy 5 0::Maybe Int
Nothing

I am curious if it is possible to  'cast' divBy to List, Identity, other monads? How?


On 6/6/07, Tillmann Rendel <[hidden email]> wrote:
Dmitri O.Kondratiev wrote:
> Monad class contains declaration
>
> *fail* :: String -> m a
>
> and provides default implementation for 'fail' as:
>
> fail s = error s
>
> On the other hand Prelude defines:
> *
> error* :: String -> a
>
> which stops execution and displays an error message.
>
> Questions:
> 1) What value and type 'error' actually returns in:
> error "some message" ?

For practical purposes:

   typechecking: every type the context asks for.
   execution: no value, because execution stops.

For theoretical purposes, error could be implemented by

   error :: String -> a
   error msg = error msg

with the extra-semantical magical side effect of printing msg and
aborting execution.

> 2) How declaration
> String -> m a
> matches with
> String -> a ?

Alpha renaming to fresh variables yields

   String -> b c
   String -> d

wich unifies by taking d := b c.

> 3) In Maybe monad:
> fail = Nothing
>
> When and how 'fail' is used in Maybe monad?

The default fail implementation is not very clever. If something fails,
execution is aborted and the user is confronted with some error message.
Some monads support richer error handling schemes. The maybe monad
encodes a succeeding computation with Just it's result, and a failed
computation with Nothing.

An example:

-- divBy is a possible failing computation in some monad
divBy :: Monad m => Int -> Int -> m Int
divBy a 0 = fail "div by zero"
divBy a b = return (a `div` b)

-- div by three succeeds
15 `divBy` 3 :: Maybe Int   ~~>   Just 5

-- div by zero fails
15 `divBy` 0 :: Maybe Int   ~~>   Nothing

-- divByAll is a shortcut for a list of divBy's
divByAll :: Monad m => Int -> [Int] -> [m Int]
divByAll a bs = map (divBy a) bs

-- div by all returns a list of computations
15 `divByAll` [3, 0] :: [Maybe Int]   ~~>   [Just 5, Nothing]

-- sequence succeeds if all computations in a list succeeds
sequence (15 `divByAll` [3, 0]) :: Maybe [Int]   ~~>   Nothing
sequence (15 `divByAll` [3, 5]) :: Maybe [Int]   ~~>   Just [5, 3]

divBy, divByAll, sequence do not know anything about Maybe, they work
for all monads, because they only use >>=, fail and return.

The idea is that Monad defines some general interface for computations,
and the various Monad instances define the exact behaviour. Maybe's
behaviour is: if a subcomputation fails, the whole computation fails.

There are other monads. consider the list monad, and it's behaviour: if
a subcomputation fails, backtrack and try some other alternative.

Tillmann





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

Re: ***DHSPAM*** Re: Newbie Q: Monad 'fail' and 'error'

Juan Carlos Arevalo Baeza-2
On Wed, 06 Jun 2007 09:29:09 -0700, Dmitri O.Kondratiev  
<[hidden email]> wrote:

> Default 'fail' implementation in Monad class will be:
> *DivBy> divBy 5 0
> Loading package haskell98-1.0 ... linking ... done.
> *** Exception: user error (div by zero)
>
> And when explicitly defining monad as Maybe it will be different:
> *DivBy> divBy 5 0::Maybe Int
> Nothing
>
> I am curious if it is possible to  'cast' divBy to List, Identity, other
> monads? How?

    It just works, and you already did it for Maybe. Just provide the type:

*Main> divBy 5 0::[Int]
[]
*Main> divBy 5 1::[Int]
[5]

    Identity fails with a stack overflow, though (GHC 6.6):

*Main> divBy 5 0::Identity Int
*** Exception: stack overflow
*Main> fail "KK" :: Identity ()
*** Exception: stack overflow
*Main> divBy 5 1::Identity Int
*** Exception: stack overflow

    Anyway...

JCAB
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe