We have looked at Generalized Algebraic Data Types. They allows us to create a domain- specific language, and evaluate it the way we want it. We can use this DSL to simulate, or execute, or for any other purpose.
In the second part, we have created a Parser with GADTs. In fact we can generalize it to a generic monad:
data Parser a where Return :: a -> Parser a Unparser :: (String -> [(a,String)]) -> (a -> Parser b) -> Parser b
Here the data constructors Return and Unparser look very similar to return and bind >>= of a monad. In fact, we can actually represent a generic instance of a monad in terms of data constructors. This is equivalent to Free monad. For more information, have a look at (https://www.andres-loeh.de/Free.pdf ...