I want to write a monad type class which will specify some basic actions for a DSL (domain-specific language) monad.
class Monad 𝔪 => MyDSLMonad 𝔪 where
type ExprTyp 𝔪 :: * -> *
var :: String -> ExprTyp 𝔪 α -> 𝔪 (ExprTyp 𝔪 α)
where ExprType
indicates the expression type, and var
will introduce a new variable declaration.
The idea is that I'll have a base monad Base
implementing MyDSLMonad
, which maybe just works on things like Int
's and Bool
's, and then higher-level abstractions will be monad transformers, which can work on higher level types.
However, the implementation for Base
's var
function might rely on the fact that it only works on Int
's and Bool
's, and require some kind of type class constraint on the var
function. So, I want something like
class Monad 𝔪 => MyDSLMonad 𝔪 where
type ExprTyp 𝔪 :: * -> *
class ValidTypes 𝔪
var :: ValidTypes 𝔪 α => String -> ExprTyp 𝔪 α -> 𝔪 (ExprTyp 𝔪 α)
instance MyDSLMonad Base where
class ValidTypes Base = MyClass
I'm aware rmonads
do this via some type caseing, but is there a nicer way? Also, I kinda like having monad transformers like StateT
in the regular monads package ... :)
There's no nicer way, yet. Max Bolingbroke is building this in GHC, hopefully it will arrive in 7.4. See https://twitter.com/mbolingbroke, here's an example: http://hpaste.org/50576