[Haskell-beginners] recursion and pattern matching

Alia alia_khouri at yahoo.com
Wed Oct 19 02:04:10 CEST 2011


Ok, so having spent some further time on this. Methinks I have a solution below.

The aha moment occurred when I fell upon the definition of foldr and then looked at
the recursive functions.


foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z []     = z
foldr f z (x:xs) = f x (foldr f z xs)

treeFold is implemented two ways, the first is as Brent advised, the second places
the accumulator after the function and follows from foldr. I suspect the first approach

is probably more practical because you can curry the accumulator away. 


The final check function verifies the equivalence of recursive and fold friendly functions. 


It was a cool exercise in all. Thanks Brent! (-:  

AK




<Test.hs>


module Test

where

data Tree a b = EmptyTree | Node a b [Tree a b] 
              deriving (Show, Read, Eq)  

t =  Node "goal" 1.0 [
        Node "a2" 0.5 [
            Node "a3" 3.0 [
                Node "a4" 1.0 [
                    Node "a5" 1.0 []
                    ]
                ]
            ],
        Node "b2" 0.5 [
            Node "b3.1" 2.0 [],
            Node "b3.2" 2.0 [
                Node "b4" 10.0 []
                ]
            ]
     ]

maximum0 [] = 0
maximum0 xs = maximum xs

sumTree :: (Num b) => Tree a b -> b
sumTree EmptyTree = 0
sumTree (Node _ value children) = value + sum (map sumTree children)

count :: Tree a b -> Int
count EmptyTree = 0
count (Node _ value children) = 1 + sum (map count children) 

depth :: Tree a b -> Int
depth EmptyTree = 0
depth (Node _ value children) = 1 + maximum0 (map depth children)

treeFold :: c -> (a -> b -> [c] -> c) -> Tree a b -> c
treeFold acc f EmptyTree = acc
treeFold acc f (Node name value children) = f name value (map (treeFold acc f) children)

treeFold' :: (a -> b -> [c] -> c) -> c -> Tree a b -> c
treeFold' f z EmptyTree = z
treeFold' f z (Node name value children) = f name value (map (treeFold' f z) children)

sumTree' :: String -> Double -> [Double] -> Double
sumTree' name value xs = value + sum xs

count' :: (Num c) => a -> b -> [c] -> c
count' name value xs = 1 + sum xs

depth' :: (Num c, Ord c) => a -> b -> [c] -> c
depth' name value xs = 1 + maximum0 (xs)


check = [ count t       == treeFold' count' 0 t
             , sumTree t  == treeFold' sumTree' 0 t
             , depth t       == treeFold' depth' 0 t
             ]


<Test.hs>



More information about the Beginners mailing list