<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>