Dear Hask'lers, I'm working on a graph generator that involves a lot of random selection out of a list of vertices. Basically, there are functions that look a little like this:
select vs = randomRM (0,length vs - 1) >>= return . (vs !!) where randomRM is a lot like Random.randomRIO, except that it is not in the IO monad, but rather in any monad, i.e. class Monad m => RandomM m where randomM :: m a randomRM :: (a,a) -> m a instance RandomM IO where randomM = randomIO randomRM = randomRIO The problem is, obviously, that when the list of vertices (vs) is empty, "select vs" will result in an error. The Prelude defines (!!) as: xs !! n | n < 0 = error "Prelude.!!: negative index" [] !! _ = error "Prelude.!!: index too large" (x:_) !! 0 = x (_:xs) !! n = xs !! (n-1) The function 'error' is implemented (at least in GHC) using Control.Exception.throw. Unfortunately, 'catch' does not seem to work. From ghci: Prelude> catch (return $ [] !! 0) (const $ putStrLn "foo" >> return 42) *** Exception: Prelude.(!!): index too large Is there any way to catch errors in functions in libraries (like the Prelude)? This is made even more necessary by the fact that the default implementation for 'fail' in a monad is 'error'. I would already be happy if I could make all applications of error change into applications of fail, as defined in my monad. Preferably, though, I would not even need a failure mechanism in my own monad, but rather have an ErrorMonad (or something similar) and just have class Monad m => ErrorMonad error m | m -> error where onError :: m a -> (error -> a) -> a For now, I simply reimplement the functions I need that give errors. Regards, Philip _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell