Say that I have got a GADT like this:
data Term a where
Lit :: a -> Term a
Succ :: Term Int -> Term Int
IsZero :: Term Int -> Term Bool
If :: Term Bool -> Term a -> Term a -> Term a
Is it possible to store Succ (Lit 2)
and IsZero (Succ (Lit 2))
inside the State monad transformer, as a value of the internal state?
The issue here being those two are of different types, and I don't know how the s
of StateT s m a
should be typed.
Edit: ATerm
solved the initial question of how to store different GADT
in the state, the issue now is since the type is lost it seemed impossible to compare the old and new state.
Edit: Final answer.
After going back and forth with @luqui, here's the full code snippet that answers this question.
Feel free to fork this repl and have a try.
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
import Data.Typeable
data Term a where
Lit :: a -> Term a
Succ :: Term Int -> Term Int
IsZero :: Term Int -> Term Bool
If :: Term Bool -> Term a -> Term a -> Term a
deriving instance (Eq a) => Eq (Term a)
data ATerm where
ATerm :: (Typeable a, Eq a) => Term a -> ATerm
instance Eq ATerm where
ATerm t == ATerm u
| Just t' <- cast t = t' == u
| otherwise = False
main :: IO ()
main = return ()