haskellrecursiontreealgebraic-data-typesnon-exhaustive-patterns

How to measure the size of a MultTree in Haskell?


I'm quite new to Haskell and therefore not very familiar with it.

The following method is to measure the size of a MultTree.

A MultTree includes Index nodes that contain two Int's and can have an arbitrary amount of children. Then there's also Data nodes that contain one Int and can have no children. So what the method should determine is, how long the longest 'branch' is.

My approach so far:

data MultTree a = Index a a [MultTree a] | Data a deriving Show

size :: MultTree a -> Int
size (Index a b []) = 1
size (Index a b [Index c d [e]]) = size (Index c d [e]) + 1

It does compile, but when trying to use it, I get "non-exhaustive patterns in function size". Even if I wouldn't get that error, I know it wouldn't work the way I wanted it to work.

But somehow I can't come up with a solution to the problem.

I would appreciate every kind of help.

Thank you already in advance!


Solution

  • You write:

    "So what the method should determine is, how long the longest 'branch' is."

    It's not "size", it's usually called "depth":

    depth :: MultTree a -> Int
    

    So what do we have? a are the values, present either in Index branching nodes, or in Data leaf nodes:

    data MultTree a = Index a a [MultTree a] 
                    | Data a 
                    deriving Show
    
    depth (Data a)          = 0   -- or 1, whatever you prefer
    depth (Index _ _ trees) = 
    

    well, we have no use for the values themselves, and as for the trees, if only we could find the depth of each one of them, we could then find the maximum, with

        let max_depth = maximum [ find_depth t | t <- trees ]
        in
            max_depth + 1
    

    Now on to writing that find_depth function. Its desired type, determined by how we're using it, is find_depth :: MultTree a -> Int. Well,

    (the rest is intentionally left blank)




    Oh, and the reason for the error is, [e] as a type stands for "a list of e-type values"; but as a pattern, it stands for "a singleton list of one value" -- and when there are more than one values in that list such case isn't covered, hence the "non-exhaustive patterns" error, i.e. there's need for more patterns to cover those cases but they are missing.

    Similarly, [Index c d [e]] as a pattern stands for "a singleton list of one value, of type MultTree a, which matches the pattern Index c d [e] where both c and d are a-type values, and [e] is a singleton list of one value of the type which is determined by the MultTree a type -- i.e., again, MultTree a:

    data MultTree a = Index a a [MultTree a] 
                    | ...