Skip to main content
edited body
Source Link
Petr
  • 3.1k
  • 17
  • 33

The implementation isn't correct, because it doesn't traverse sub-trees. Consider

Node 1 [Node 2 [Node 3 []]]

Then your folding function will only fold over 1 and 2, but not over 3.

If you have a recursive structure like this, a folding function over it must also be recursive. Otherwise it won't be able to traverse arbitrarily large recursive structure.

For the other question: If you specialize the folding function as

treeFold :: ([Char] -> [[Char]] -> [Char]) -> (Char -> [Char])
         -> Tree Char -> [Char]

by setting b = [Char], you get what you're looking for - converting a Tree Char to String. You just need to supply the two function for folding, for example

treeFold (\x ys -> x ++ concat ys) (: [])

Update: The signature also isn't correct. The general rule is that the folding function should have one additional argument for each constructor of the data type where recursive types (here Tree a) are replaced by the result of the fold:

treeFold :: (a -> [b] -> ab) -> Tree a -> b

For example for a list you have 2 constructors: (:) :: a -> [a] -> [a] and [] :: [a], so its folding function is

foldr :: (a -> b -> b) -> b -> [a] -> b

The implementation isn't correct, because it doesn't traverse sub-trees. Consider

Node 1 [Node 2 [Node 3 []]]

Then your folding function will only fold over 1 and 2, but not over 3.

If you have a recursive structure like this, a folding function over it must also be recursive. Otherwise it won't be able to traverse arbitrarily large recursive structure.

For the other question: If you specialize the folding function as

treeFold :: ([Char] -> [[Char]] -> [Char]) -> (Char -> [Char])
         -> Tree Char -> [Char]

by setting b = [Char], you get what you're looking for - converting a Tree Char to String. You just need to supply the two function for folding, for example

treeFold (\x ys -> x ++ concat ys) (: [])

Update: The signature also isn't correct. The general rule is that the folding function should have one additional argument for each constructor of the data type where recursive types (here Tree a) are replaced by the result of the fold:

treeFold :: (a -> [b] -> a) -> Tree a -> b

For example for a list you have 2 constructors: (:) :: a -> [a] -> [a] and [] :: [a], so its folding function is

foldr :: (a -> b -> b) -> b -> [a] -> b

The implementation isn't correct, because it doesn't traverse sub-trees. Consider

Node 1 [Node 2 [Node 3 []]]

Then your folding function will only fold over 1 and 2, but not over 3.

If you have a recursive structure like this, a folding function over it must also be recursive. Otherwise it won't be able to traverse arbitrarily large recursive structure.

For the other question: If you specialize the folding function as

treeFold :: ([Char] -> [[Char]] -> [Char]) -> (Char -> [Char])
         -> Tree Char -> [Char]

by setting b = [Char], you get what you're looking for - converting a Tree Char to String. You just need to supply the two function for folding, for example

treeFold (\x ys -> x ++ concat ys) (: [])

Update: The signature also isn't correct. The general rule is that the folding function should have one additional argument for each constructor of the data type where recursive types (here Tree a) are replaced by the result of the fold:

treeFold :: (a -> [b] -> b) -> Tree a -> b

For example for a list you have 2 constructors: (:) :: a -> [a] -> [a] and [] :: [a], so its folding function is

foldr :: (a -> b -> b) -> b -> [a] -> b
added 472 characters in body
Source Link
Petr
  • 3.1k
  • 17
  • 33

The implementation isn't correct, because it doesn't traverse sub-trees. Consider

Node 1 [Node 2 [Node 3 []]]

Then your folding function will only fold over 1 and 2, but not over 3.

If you have a recursive structure like this, a folding function over it must also be recursive. Otherwise it won't be able to traverse arbitrarily large recursive structure.

For the other question: If you specialize the folding function as

treeFold :: ([Char] -> [[Char]] -> [Char]) -> (Char -> [Char])
         -> Tree Char -> [Char]

by setting b = [Char], you get what you're looking for - converting a Tree Char to String. You just need to supply the two function for folding, for example

treeFold (\x ys -> x ++ concat ys) (: [])

Update: The signature also isn't correct. The general rule is that the folding function should have one additional argument for each constructor of the data type where recursive types (here Tree a) are replaced by the result of the fold:

treeFold :: (a -> [b] -> a) -> Tree a -> b

For example for a list you have 2 constructors: (:) :: a -> [a] -> [a] and [] :: [a], so its folding function is

foldr :: (a -> b -> b) -> b -> [a] -> b

The implementation isn't correct, because it doesn't traverse sub-trees. Consider

Node 1 [Node 2 [Node 3 []]]

Then your folding function will only fold over 1 and 2, but not over 3.

If you have a recursive structure like this, a folding function over it must also be recursive. Otherwise it won't be able to traverse arbitrarily large recursive structure.

For the other question: If you specialize the folding function as

treeFold :: ([Char] -> [[Char]] -> [Char]) -> (Char -> [Char])
         -> Tree Char -> [Char]

by setting b = [Char], you get what you're looking for - converting a Tree Char to String. You just need to supply the two function for folding, for example

treeFold (\x ys -> x ++ concat ys) (: [])

The implementation isn't correct, because it doesn't traverse sub-trees. Consider

Node 1 [Node 2 [Node 3 []]]

Then your folding function will only fold over 1 and 2, but not over 3.

If you have a recursive structure like this, a folding function over it must also be recursive. Otherwise it won't be able to traverse arbitrarily large recursive structure.

For the other question: If you specialize the folding function as

treeFold :: ([Char] -> [[Char]] -> [Char]) -> (Char -> [Char])
         -> Tree Char -> [Char]

by setting b = [Char], you get what you're looking for - converting a Tree Char to String. You just need to supply the two function for folding, for example

treeFold (\x ys -> x ++ concat ys) (: [])

Update: The signature also isn't correct. The general rule is that the folding function should have one additional argument for each constructor of the data type where recursive types (here Tree a) are replaced by the result of the fold:

treeFold :: (a -> [b] -> a) -> Tree a -> b

For example for a list you have 2 constructors: (:) :: a -> [a] -> [a] and [] :: [a], so its folding function is

foldr :: (a -> b -> b) -> b -> [a] -> b
Source Link
Petr
  • 3.1k
  • 17
  • 33

The implementation isn't correct, because it doesn't traverse sub-trees. Consider

Node 1 [Node 2 [Node 3 []]]

Then your folding function will only fold over 1 and 2, but not over 3.

If you have a recursive structure like this, a folding function over it must also be recursive. Otherwise it won't be able to traverse arbitrarily large recursive structure.

For the other question: If you specialize the folding function as

treeFold :: ([Char] -> [[Char]] -> [Char]) -> (Char -> [Char])
         -> Tree Char -> [Char]

by setting b = [Char], you get what you're looking for - converting a Tree Char to String. You just need to supply the two function for folding, for example

treeFold (\x ys -> x ++ concat ys) (: [])