Brian Hulley wrote:
Chris Kuklewicz wrote:
This is how I would write getLeaves, based on your GADT:

data IsLeaf
data IsBranch

newtype Node = Node { getNode :: (forall c. ANode c) }
[snip]
Thanks Chris - that's really neat!
I see it's the explicit wrapping and unwrapping of the existential that solves the typechecking problem,

Actually, Node is universally quantified. This makes it not inhabitated given the ANode GADT. So, you can consume a Node, but you can not produce a non-bottom one.

Existential quantification version:

data IsLeaf
data IsBranch

data Node = forall c . Node ( ANode c )

data ANode :: * -> * where
Branch :: String -> String -> (ANode a,ANode b) -> [Node] -> ANode IsBranch
    Leaf :: String -> String -> ANode IsLeaf

getLeaves :: ANode a -> [ANode IsLeaf]
getLeaves (Branch _ _ (l1,l2) rest) = getLeaves l1 ++ getLeaves l2 ++
                                      concatMap getLeaves' rest
getLeaves x@(Leaf {}) = [x]

getLeaves' :: Node -> [ANode IsLeaf]
getLeaves' (Node x) = getLeaves x


Regards,
Zun.
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to