Addendum:<br>
<font size="2"><font color="#16569e">(18:19:50) </font></font><font color="#16569e"><b><font size="3">vincenz:</font></b></font><font size="3"> anyways the haskell-cafe post is orthogonal to this safety issue</font><br>
<font size="2"><font color="#16569e">(18:20:46) </font></font><font color="#16569e"><b><font size="3">vincenz:</font></b></font><font size="3">
it's about the inability to use a generic annotation data-type with any
generic indirect composite ADT without introducing a third data
constructor if one wants recursion</font><br>
<font size="2"><font color="#16569e">(18:21:33) </font></font><font color="#16569e"><b><font size="3">vincenz:</font></b></font><font size="3"> data Foo a = A a;   date Note a n = Note { data :: a, info :: n} ;    type RecNoteFoo = Note (Foo RecNoteFoo)  Int
</font><b><font size="3"></font></b><br>
<font size="2"><font color="#af7f00">(18:25:53) </font></font><font color="#af7f00"><b><font size="3">audreyt:</font></b></font><font size="3"> vincenz: that is a good summary.</font><br>
<font size="2"><font color="#bc8f8f">(18:26:17) </font></font><font color="#bc8f8f"><b><font size="3">audreyt:</font></b></font><font size="3"> sugar selectors, smart constructors, SYB, etc.</font><br>
<font size="2"><font color="#bc8f8f">(18:26:24) </font></font><font color="#bc8f8f"><b><font size="3">audreyt:</font></b></font><font size="3"> but the core problem seems like a real limitation</font><br><br><div><span class="gmail_quote">
On 7/5/06, <b class="gmail_sendername">Christophe Poucet</b> &lt;<a href="mailto:christophe.poucet@gmail.com">christophe.poucet@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><span style="font-family: courier new,monospace;">Hello,</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
I use the Indirect Composite pattern a lot, and this means that
typically, especially with recursive types (such as an AST), you end up
with a lot of data-constructors.&nbsp; I understand that it is not
possible to have pure cyclic types (because haskell requires
iso-recursive and not equi-recursive types).&nbsp; However I wonder why
certain cases can not be allowed.&nbsp; </span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
For instance, assume the following somewhat simplified AST:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
data Exp e = </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp; ELet String e e&nbsp;&nbsp;&nbsp; -- let x = a in b</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp; | ECond e e e&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- If then else construct</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
Now if I wanted to decorate this structure, I would use something like:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
data AnnotExp a = AE {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; unAE :: Exp (AnnotExp a),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; note :: a</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">However, and this
example might be slightly too trivial to motivate it, however it does
exemplify what can be done, one might not want to annotate at all and
just have a recursive data AST.&nbsp; At this point, one either uses
AnnotExp () or creates a new data type.&nbsp; It would be nice if
instead one could use cyclic type-declarations, with the knowledge that
we're going through a data-constructor and hence the type iso-recursive
and not equi-recursive:</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">type AST = Exp AST&nbsp; -- This is iso-recursive as it goes through the data constructors ELet and ECond</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Sadly this is not
possible with the current GHC (I'm using 6..4.2).&nbsp; Is this
possible with 6.6?&nbsp; Is there any reason why this is not
possible.&nbsp; Feedback regarding this is welcome.&nbsp; A more
motivating example can be seen below.</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Cheers,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Christophe</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">-----------------------------</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">data Exp var ident func exp stm =</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
ELit
Lit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Literals</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; | EVar ident&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ^ Identifiers</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; | EData Const [exp]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ^ Data Constructors</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; | ECall func&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ^ Function Calls</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; | ELet var stm stm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ^ Scoping</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; | ECond exp stm stm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ^ Conditional</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; | ELoop exp stm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ^ Looping</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; deriving (Eq, Show)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">data AExp exp annot = AExp {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; unAExp&nbsp;&nbsp;&nbsp; :: exp,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; aexpNote&nbsp; :: annot,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; aexpLoc&nbsp;&nbsp; :: Location</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">type UnCorExp var annot =</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; Exp</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
var&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Let-binders</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
var&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Named identifiers</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; (Ident, [AExp UnCorExp var annot])&nbsp;&nbsp;&nbsp; -- ^ Function calls</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
(AExp UnCorExp var
annot)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Expressions</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
(AExp UnCorExp var
annot)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Statements</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">-- Flattened AST: function parameters can only be variables, similar for while- and if- conditions</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">type UnSimExp var annot&nbsp; </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; Exp</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
var&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Let-binders</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
var&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Named identifiers</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
(Ident,
[var])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Function calls</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
(var)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Expressions</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;
(AExp UnSimExp var
annot)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-- ^ Statements</span><br style="font-family: courier new,monospace;">
<br>

</div></blockquote></div><br>