[Haskell-cafe] Trouble understanding records and existential types
Roberto Zunino
zunino at di.unipi.it
Sat Jan 27 12:09:41 EST 2007
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.
More information about the Haskell-Cafe
mailing list