packages feed

throwable-exceptions-0.1.0.5: example/Main.hs

{-# LANGUAGE TemplateHaskell #-}

module Main where

import Control.Exception.Safe (throwM, MonadCatch, catch, SomeException)
import Control.Exception.Throwable (GeneralException(..), generalException, IndexOutOfBoundsException(..))
import Control.Exception.Throwable.TH (declareException)

{- !! These line is needed by declareException !! -}
import Control.Exception.Safe (Exception)
import Data.Typeable (Typeable)
{- ---------------------------------------------- -}


-- This is same as
--
-- data MyException a = MyException
--  { myExceptionCause :: String
--  , MyExceptionClue  :: a
--  } deriving (Show, Typeable)
-- instance (Typeable a, Show a) => Exception (MyException a)
--
declareException "MyException"


main :: IO ()
main = do
  print $ ([1..4] `at` 5 :: Either SomeException Int)
  print $ MyException "hi" 10
  print $ myException "poi"
  print (foo :: Either SomeException Int)
--
-- vvv  output result  vvv
--
-- Left IndexOutOfBoundsException: "index is too big"
-- MyException: "hi"
-- MyException: "poi"
-- Left FooException: poi poi poi !?


-- IndexOutOfBoundsException,
-- IOException',
-- IllegalArgumentException,
-- and GeneralException is presented by default.
at :: (MonadCatch m, Typeable a, Show a) => [a] -> Int -> m a
at xs index = do
  if index < length xs
    then return $ xs !! index
    else throwM $ IndexOutOfBoundsException "index is too big" (xs, index)
    --else throwM $ indexOutOfBoundsException' "index is too big"
    -- You can use above code without some clue


-- If you don't want to use TemplateHaskell (Control.Exception.Throwable.TH),
-- you can use GeneralException and generalException instead !
--
-- data GeneralException a = GeneralException
--   { exceptionName  :: String -- ^ This should be named by 'PascalCase' for show, for example: "MyOperation", "Database"
--   , exceptionCause :: String -- ^ The message for the cause of the exception
--   , exceptionClue  :: a      -- ^ The clue of the exception. This can be anything of Show instance
--   }
-- 
-- generalException :: String -> String -> GeneralException ()
-- generalException name cause = GeneralException name cause () 
--
foo :: (MonadCatch m, Typeable a, Show a) => m a
foo = throwM $ generalException "FooException" "poi poi poi !?"
-- This is same as `GeneralException "FooException" "poi poi poi !?" ()`