[Haskell-cafe] Newbie Q: Monad 'fail' and 'error'
Dmitri O.Kondratiev
dokondr at gmail.com
Wed Jun 6 12:29:09 EDT 2007
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 <rendel at rbg.informatik.tu-darmstadt.de> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20070606/8557c095/attachment-0001.htm
More information about the Haskell-Cafe
mailing list