In Haskell, it is said that any ADT can be expressed as sum of products. I'm trying to find a flat type that is isomorphic to Tree
, on Data.Tree
.
Tree a = Node a [Tree a] -- has a nested type (List!)
I want to write a functionally identical definition for Tree without nested types:
Tree = ??? -- no nested types allowed
For that, I tried writing the recursive relation for the type algebras:
L a = 1 + a * L a
T a = a * L (T a)
Inlining L, I had:
T a = a * (1 + T a * L (T a))
T a = a * (1 * T a * (1 + T a * L (T a)))
T a = a * (1 + T a * (1 + T a * (1 + T a * L (T a))))
That wasn't going anywhere, so I stopped and did the multiplications, leaving me with:
T a = a + a * T a + a * T a * T a ...
Which is the same as:
T a = a * (T a) ^ 0 + a * (T a) ^ 1 + a * (T a) ^ 2 ...
That is a sum of products, but it is infinite. I can't write that in Haskell. By abusing the algebra:
(T a) - (T a) ^ 2 = a * T a
- (T a) ^ 2 - a * T a + (T a) = 0
Solving for T a
, I found that:
T a = 1 - a
Which obviously doesn't make any sense. So, back to the original question: how do I flatten Tree
from Data.Tree
so I can write a type that is isomorphic to it without nested types?
This question isn't a duplicate of my previous question. The last one is about representing nested types with the Scott Encoding, for which the correct answer is "ignore the nesting". This one proceeds to ask how to flatten a nested type anyway (since it is needed for a particular use of the Scott Encoding, but not obligatory in general).
Once you got to
you could continue
so you arrive at
I'm not sure to what extent this is an instance of a general procedure, however.