<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Hi Ducis,<br>
    </p>
    <p>you can parametrise over type variables of other kinds than just
      *.</p>
    <p>If what you write is really what you want, the most
      straightforward answer is simply</p>
    <pre> data ExprG f
            = Var      VarName
            | Enclosed VarName (f Expr) VarName
            | Prefix   (f Expr) (f Expr)
            | Ternary  (f Expr) VarName (f Expr) VarName (f Expr)
        
        type Expr  = ExprG Identity -- From Data.Functor.Identity
        type ExprL = ExprG []
        type ExprD = ExprG DList</pre>
    <p>There is no mention of the word "functor" because you will have
      to add that constraint to the usage sites.</p>
    <p>Downside: notice that the deriving clauses are gone because the
      instances aren't as easy to derive any more. Even the simplest and
      most harmless way I know to get that possibility back involves two
      language extensions: <tt>StandaloneDeriving</tt> and <tt>FlexibleInstances</tt>.
      With those you can write</p>
    <pre> deriving instance Show (ExprG Identity)
        deriving instance Show (ExprG [])
        deriving instance Show (ExprG DList)
        deriving instance Eq   (ExprG Identity)
        :</pre>
    <p>I suspect though that what you actually want, but didn't write,
      is more along the lines of</p>
    <pre> data ExprL = … | EnclosedL VarName [ExprL]       VarName | …   -- using ExprL instead of Expr on the right side

        data ExprD = … | EnclosedD VarName (DList ExprD) VarName | …   -- using ExprD instead of Expr on the right side
</pre>
    <p>The good news is that if you have the first solution, this step
      is rather simple. Because you can just use replace <tt>Expr</tt>
      with <tt>ExprG f</tt> again:<br>
    </p>
    <pre> data ExprG f
            = Var      VarName
            | Enclosed VarName (f (ExprG f)) VarName
            | Prefix   (f (ExprG f)) (f (ExprG f))
            | Ternary  (f (ExprG f)) VarName (f (ExprG f)) VarName (f (ExprG f))</pre>
    <p>The better news is that although this looks repetitive and hard
      to read, it's well on the way to discovering the magic of the Free
      Monad.</p>
    <p>Hope this helps.<br>
    </p>
    <p>Cheers,<br>
      MarLinn<br>
    </p>
    <p><br>
    </p>
  </body>
</html>