On Tuesday 24 August 2010 13:09:56, Thomas wrote:
> Hello!
>> I have a question about type variables.
> The following works:
>> type XMLCallback a = (XMLTreeNode -> a -> [Int] -> [XMLTreeNode] -> a)
>> xmlTreeFold :: XMLCallback a -> a -> Maybe XMLTreeNode -> Maybe a
> xmlTreeFold _ _ Nothing = Nothing
> xmlTreeFold func acc (Just tree) =
> Just (xmlTreeWalkerWithContext func acc tree [] [])
>> testFold :: XMLCallback [(XMLTreeNode, [Int], [XMLTreeNode])]
> testFold node a is ns =
> if (length is) > 1 then ((node, is, ns):a) else a
Do not use `if length list > 1', if the list is long, that takes long too.
Use `if not (null $ drop 1 list)'.
>> => xmlTreeFold testFold [] tree
>> But if I change the type declaration of 'testFold' to:
> testFold :: XMLCallback a
> it will not compile.
>> I thought that 'a' is a type /variable/ thus able to hold any type, for
> example, but not limited to '[(XMLTreeNode, [Int], [XMLTreeNode])]'.
Right. However, the definition of testFold says a can't be *any* type.
In the then-branch, the result is
(node, is, ns) : a,
which is a list, and forces a to be a list too, so the type of testFold
cannot be more general than
XMLCallback [a]
(and that should compile).
> Why do I need to be that much more specific in the declaration for
> 'testFold'? Especially since in the declaration of 'xmlTreeFold' the
> 'XMLCallback a' is well received.
In the definition of xmlTreeFold, nothing restricts the type of the
accumulator argument, so it can be anything.
>> Thanks for any insights,
> Thomas