0

I am trying to apply sum using id function while giving input to program.but i am with below. any guidance is much appreciated.

data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Eq, Show)
reduce_tree :: Tree a -> (a -> b) -> (b -> a -> b -> b) -> b
reduce_tree (Leaf v) = [v]
reduce_tree (Node left root right) = reduce_tree left ++ [root] ++   reduce_tree right

input as follows:

ghci> reduce_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5)))
                   id sum
                   where sum t1 v t2 = t1 + v + t2
15
m0nhawk
  • 22,980
  • 9
  • 45
  • 73
John
  • 29
  • 5
  • 1
    I don't understand your question, looks like it's working as intended... – luqui Nov 20 '15 at 07:13
  • @luqui: i want to do sum on tree to list with the below function type but i m not getting any idea , reduce_tree :: Tree a -> (a -> b) -> (b -> a -> b -> b) -> b – John Nov 20 '15 at 07:17
  • @luqui : with the below function type i am trying to do sum of tree to list reduce_tree :: Tree a -> (a -> b) -> (b -> a -> b -> b) -> b – John Nov 20 '15 at 07:35

2 Answers2

3

Since I don't understand your question completely, here are some observations:

  • reduce_tree's type signature suggests that it should have more arguments than you give it.

    If f is a function that maps values of type a to values of type b, and g is what appears to be an accumulating function of three arguments (although I'm unsure why two are not enough), then

    reduce_tree :: Tree a -> (a -> b) -> (b -> a -> b -> b) -> b
    reduce_tree (Leaf v) f g = ...
    reduce_tree (Node left v right) f g = ...
    
  • If reduce_tree is in fact a reduce function, and not one that simply flattens trees into lists, you may draw inspiration from Data.Foldable.

    data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Show, Eq)
    
    treefold :: (a -> b -> b) -> b -> Tree a -> b
    treefold f acc (Leaf x) = f x acc
    treefold f acc1 (Node left x right) =
      let acc2 = treefold f acc1 right
          acc3 = f x acc2
          acc4 = treefold f acc3 left
      in acc4
    

    With such a function you can either flatten or sum the elements of a tree:

    flattenTree :: Tree a -> [a]
    flattenTree tree = treefold (:) [] tree
    
    sumTree :: Num a => Tree a -> a
    sumTree tree = treefold (+) 0 tree
    
  • The only bell that rings when you say "apply sum using id function" is that perhaps you wish to use continuations. This is already covered thoroughly in e.g. Haskell: tail recursion version of depth of binary tree and concisely in Tail-recursion on trees (Standard ML). A Haskell equivalent would be:

    treefold :: (a -> b -> b) -> b -> Tree a -> b
    treefold f acc tree = tf f acc tree id
      where
        tf f acc (Leaf x) k = k (f x acc)
        tf f acc (Node left x right) old_k = tf f left acc new_k
          where
            new_k = \acc -> tf f right (f x acc) old_k
    

    Now sumTree can be defined in the exact same way as before, except it would use folding as well as the identity function as the initial continuation. Or you could extract the helper function tf to the top-level if you want to feed the traversal function with the function id yourself.

Community
  • 1
  • 1
sshine
  • 15,635
  • 1
  • 41
  • 66
  • below is how you told me to find sum of tree code: data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Show, Eq) treefold :: (a -> b -> b) -> b -> Tree a -> b treefold f acc (Leaf x) = f x acc treefold f acc1 (Node left x right) = let acc2 = treefold f acc1 right acc3 = f x acc2 acc4 = treefold f acc3 left in acc4 sumTree :: Num a => Tree a -> a sumTree tree = treefold (+) 0 tree – John Nov 20 '15 at 22:28
  • ghci> sumTree (Node (Leaf 1) 2 (Node (Leaf 3) 4 (Leaf 5))) 15 – John Nov 20 '15 at 22:28
  • but how can i find sum at run time as below : data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Show, Eq) treefold :: (a -> b -> b) -> b -> Tree a -> b treefold f acc (Leaf x) = f x acc treefold f acc1 (Node left x right) = let acc2 = treefold f acc1 right acc3 = f x acc2 acc4 = treefold f acc3 left in acc4 flattenTree :: Tree a -> [a] flattenTree tree = treefold (:) [] tree – John Nov 20 '15 at 22:29
  • ghci> flattenTree (Node (Leaf 1) 2 (Node (Leaf 3) 4 (Leaf 5)))id sum where sum t1 v t2 = t1 + v + t2 then ouput : 15 – John Nov 20 '15 at 22:32
2

Oh, if I understand correctly, I think you are just trying to enter your example into ghci. I would recommend putting the complexity in the file:

sum_tree :: Tree Int -> Int
sum_tree t = reduce_tree t id sum
    where sum t1 v t2 = t1 + v + t2

then in ghci, after you have loaded the file that sum_tree and reduce_tree are defined in,

ghci> sum_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5))

If you must do it all in ghci, be aware that you can't use where in ghci usually, since where is only used in definitions. Use let ... in instead:

ghci> let sum t1 v t2 = t1 + v + t2 in reduce_tree (VNode (VLeaf 1) 2 (VNode (VLeaf 3) 4 (VLeaf 5))) id sum

If you for some reason don't want to use let, you can use a lambda:

ghci> reduce_tree (VNode (VLeaf 1) 2 (VLeaf 3)) id (\t1 v t2 -> t1 + v + t2)

Did I understand your question correctly?

luqui
  • 59,485
  • 12
  • 145
  • 204
  • thanks for your reply.. actually i want to give identity function and sum function in ghci itself not using let... for ex: ghci> reduce_tree (Node (Leaf 1) 2 (Node (Leaf 3) 4 (Leaf 5))) id sum where sum t1 v t2 = t1+v+t2 then the output is 15 – John Nov 20 '15 at 07:30
  • Uh, ok... I edited my answer with another suggestion. You can't use `where` in ghci. – luqui Nov 20 '15 at 07:35
  • :with the below function type i am trying to do sum of tree to list reduce_tree :: Tree a -> (a -> b) -> (b -> a -> b -> b) -> b – John Nov 20 '15 at 07:36
  • Oh of course, `reduce_tree` is wrong, I didn't notice! See other answer. – luqui Nov 20 '15 at 07:38
  • can u explain clearly with the function type i mentioned.. i got confused – John Nov 20 '15 at 08:02