{-# LANGUAGE ExistentialQuantification, StandaloneDeriving #-}

-- |
-- Module      : OAlg.Control.Exception
-- Description : general algebraic exceptions
-- Copyright   : (c) Erich Gut
-- License     : BSD3
-- Maintainer  : zerich.gut@gmail.com
--
-- General algebraic exceptions.
module OAlg.Control.Exception
  ( -- * Algebraic Exceptions
    oalgExceptionToException
  , oalgExceptionFromException
  , SomeOAlgException(..)
  , AlgebraicException(..)
  , implementation

    -- * Exports
  , Exception(..), throw
  )
  where

import Control.Exception as E
import Data.Typeable (cast)

--------------------------------------------------------------------------------
-- Algebraic exceptions

-- | The root exception for all algebraic exceptions.
data SomeOAlgException = forall e . Exception e => SomeOAlgException e

instance Show SomeOAlgException where
  show :: SomeOAlgException -> String
show (SomeOAlgException e
e) = e -> String
forall a. Show a => a -> String
show e
e
  
instance Exception SomeOAlgException

-- | embedding an exception into 'SomeOAlgException'.
oalgExceptionToException :: Exception e => e -> SomeException
oalgExceptionToException :: forall e. Exception e => e -> SomeException
oalgExceptionToException = SomeOAlgException -> SomeException
forall e. Exception e => e -> SomeException
toException (SomeOAlgException -> SomeException)
-> (e -> SomeOAlgException) -> e -> SomeException
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> SomeOAlgException
forall e. Exception e => e -> SomeOAlgException
SomeOAlgException

-- | casting an exception to 'SomeOAlgException'.
oalgExceptionFromException :: Exception e => SomeException -> Maybe e
oalgExceptionFromException :: forall e. Exception e => SomeException -> Maybe e
oalgExceptionFromException SomeException
e = do
  SomeOAlgException e
a <- SomeException -> Maybe SomeOAlgException
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e
  e -> Maybe e
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast e
a

-- | general algebraic exception which are sub exceptions of 'SomeOAlgException'.
data AlgebraicException
  = AlgebraicException String
  | Undefined String
  | ImplementationError String
  | NoPredecor
  | InvalidData String
  deriving (Int -> AlgebraicException -> ShowS
[AlgebraicException] -> ShowS
AlgebraicException -> String
(Int -> AlgebraicException -> ShowS)
-> (AlgebraicException -> String)
-> ([AlgebraicException] -> ShowS)
-> Show AlgebraicException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AlgebraicException -> ShowS
showsPrec :: Int -> AlgebraicException -> ShowS
$cshow :: AlgebraicException -> String
show :: AlgebraicException -> String
$cshowList :: [AlgebraicException] -> ShowS
showList :: [AlgebraicException] -> ShowS
Show)

instance Exception AlgebraicException where
  toException :: AlgebraicException -> SomeException
toException   = AlgebraicException -> SomeException
forall e. Exception e => e -> SomeException
oalgExceptionToException
  fromException :: SomeException -> Maybe AlgebraicException
fromException = SomeException -> Maybe AlgebraicException
forall e. Exception e => SomeException -> Maybe e
oalgExceptionFromException

--------------------------------------------------------------------------------
-- implementation -

-- | message for implementation errors. Mainly used for non-permissible or unreachable
-- patterns.
implementation :: String
implementation :: String
implementation = String
"implementation"