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