I'm just curious why I have to write this,
instance (HzMonad 𝔪, Data.Suitable.Suitable 𝔪 α, γ ~ ExprTyp 𝔪 α) => VarDecl 𝔪 γ where
var = varhz
instead of this
instance (HzMonad 𝔪, Data.Suitable.Suitable 𝔪 α) => VarDecl 𝔪 (ExprTyp 𝔪 α) where
var = varhz
-- error
Hz2/Language.hs:114:53:
Illegal type synonym family application in instance: ExprTyp 𝔪 α
In the instance declaration for `VarDecl 𝔪 (ExprTyp 𝔪 α)'
where
varhz ::
(HzMonad 𝔪, Data.Suitable.Suitable 𝔪 α) =>
String -> ExprTyp 𝔪 α -> 𝔪 (ExprTyp 𝔪 α)
What is the tilde anyway? Thanks very much.
I think the problem is that everything on the right hand side of
=>
must be either a type constructor or type variable. ExprTyp could refer to multiple differet type constructors. Replacing this with an equality constraint will indeed work, but the resulting instance will be effectively useless, since the compiler won't be able to deduce anything about γ
given that it's an ExprTyp -- ExprTyp could be aliased to anything.
In my situation -- I'm trying to write a DSL monad -- the solution is to wrap all uses of the associated type in a newtype constructor. For example, if we start with,
class MyDSL m a where
type ExprTyp m :: * -> *
printE :: ExprTyp m a -> m ()
then wrapping this will result in
newtype ExprT a = ExprT a
class MyDSL m a where
type ExprTyp m :: * -> *
printE :: ExprT (ExprTyp m a) -> m ()
Then, for example, the variable declarations (I was writing code for tupled variable declarations) could be,
instance (HzMonad 𝔪, Data.Suitable.Suitable 𝔪 α, γ ~ ExprTyp 𝔪 α) => VarDecl 𝔪 (ExprT γ)
instance (Monad 𝔪, VarDecl 𝔪 α, VarDecl 𝔪 β) => VarDecl 𝔪 (α, β)
please post a comment if something is unclear.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With