module Main (main) where

import Data.Coerce (coerce)
import Control.Monad.Identity (Identity(..))
import Control.Monad.Trans.Except (ExceptT(..), Except, runExcept)

import qualified GStateT as GS
import GStateT ( GStateT(..), Swap(..) )

-- Fake Alex with state Int
type AlexState = Int
newtype Alex a = Alex {unAlex :: AlexState -> Either String (AlexState, a) }

-- Alias the swapped GStateT as StateT
type StateT = GS.SwapStateT
runStateT :: Monad m => StateT s m a -> s -> m (s, a)
runStateT m = GS.runSwapStateT m

main :: IO ()
main = do
    let x = (Alex $ \i -> Right (i, i+1)) :: Alex Int
        y = coerce x :: StateT AlexState (Except String) Int
    print $ unAlex x 1
    print $ runExcept $ runStateT y 1
    print $ runExcept $ GS.execStateT y 1
    print $ runExcept $ GS.evalStateT y 1
