|
Boost : |
From: Eric Friedman (ebf_at_[hidden])
Date: 2003-10-20 17:45:35
Brian McNamara wrote:
> Is it possible to use tuple/variant to define recursive algebraic
> datatypes? In Haskell I might say something like
>
> type Operand = String -- e.g. "+" or "<<"
> data ExprTreeNode = ETN Operand ExprTree ExprTree
> data ExprTreeLeaf = ETL Int
> type ExprTree = Either ExprTreeLeaf ExprTreeNode
>
> If I try to translate this directly into C++, I might say
>
> typedef std::string Operand;
> typedef tuple<Operand,ExprTree*,ExprTree*> ExprTreeNode;
> typedef int ExprTreeLeaf;
> typedef variant<ExprTreeLeaf,ExprTreeNode> ExprTree;
>
> except that this doesn't work, since we need to somehow forward-declare
> that ExprTree is a typename or something.
>
> Is there any way to do this? Is there a good way to do this?
How about this:
typedef std::string Operand;
typedef int ExprTreeLeaf;
typedef recursive_variant<
ExprTreeLeaf
, tuple< Operand, recursive_variant_*, recursive_variant_* >
>::type ExprTree;
typedef tuple< Operand, ExprTree*, ExprTree* > ExprTreeNode;
[You actually don't need pointers- I'm just trying to mirror your code.]
Unfortunately, I haven't yet provided reference documentation for
recursive_variant. (But do see http://tinyurl.com/rnue for a tutorial on
its use.)
> It kinda boils down to the same problem as this one:
>
> typedef std::pair< int, Cons* > Cons; // oops, rats
>
> which I've seen discussed before, but can't find good resolutions to.
> My hunch is that there's no good way to do this unless C++ adds language
> support (e.g. to forward-declare typedef typenames), but I'd be thrilled
> if someone would prove me wrong.
Yes, the recursive_variant solution is a bit of a hack. Hopefully it
works for you. (I'd appreciate feedback on your success with it.)
Eric
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk