So, I have that Huffman tree, that is used for encoding strings. And I have defined the function plant, but I am not sure whether my tree is not tilting too much only to the one side. Here is my code:
data HuffTree
= Leaf Char
| HuffTree |*| HuffTree
deriving (Eq, Show)
|*| is an infix Constructor.
plant :: [(Char,Int)] -> HuffTree
plant [(x,y)] = (Leaf x)
plant ((x,y):xs) = plant xs |*| (Leaf x)
For me, it looks one-sided and hence it really doesn`t implies the encoding idea, since not being a real binary tree. How could I turn it into a regular binary tree?
You're not constructing the Huffman tree correctly. The process is supposed to go like this:
Turn all the source symbols into single-element huffman trees
Pair each source symbol up with its frequency into a big list of tree/frequency pairs.
If there is just one tree/frequency pair left, that tree is your Huffman tree.
Else remove the two trees/frequency pairs with the lowest freqyency, combine the trees and add the frequencies to make a new tree/frequency pair, and add it back to the list.
Goto 3.
So I'd change it to plant :: [(HuffTree,Int)] -> HuffTree. In the second case I'd sort the elements, pluck off the first two, combine them, then call plant recursively. You might also want to swith to (Int,HuffTree) pairs so that you can use the default sort implementation. You'd also need to add Ord to your HuffTree deriving clause.
Related
I'm trying to write a haskell function that will return the max int inside a binary tree of integers. My binary tree is defined as follows:
data Tree = Node Int Tree Tree | Leaf Int
deriving (Eq,Show)
The way I understand it this declaration is saying that for the 'Tree' data type, it can either be a single leaf int, or be a subtree containing two more trees.
So my maxInt function will look something like this ( I think )
maxInt :: Tree -> Int --maxInt function receives Tree, returns int
maxInt --something to detect if the Tree received is empty
--if only one node, return that int
--look through all nodes, find largest
and so when my function is given something like
maxInt (Node 5 (Leaf 7) (Leaf 2)) , the correct value for maxInt to return would be 7.
I'm new to haskell and don't really know where to start with this problem, I would really appreciate some guidance. Thank you
Let me start it for you:
maxInt :: Tree -> Int
maxInt (Leaf x) = ?
maxInt (Node x l r) = ?
You may find it helpful to use the standard function max, which takes two arguments and returns their maximum:
max 3 17 = 17
To begin with, we have this datatype:
data Tree = Node Int Tree Tree | Leaf Int
deriving (Eq,Show)
That means, we have two constructors for things of type Tree: either we have a Leaf with a single Int value, or we have a Node which allows us to represent bigger trees in a recursive fashion.
So, for example we can have these trees:
Leaf 0
And more complex ones:
Node 3 (Leaf 0) (Leaf 4)
Recall that this tree representation have information both in the leaves and in the nodes, so for our function we will need to take that into account.
You guessed correctly the type of the function maxInt, so you are halfway through!
In order to define this function, given we have a custom defined datatype, we can be confident in using pattern-matching.
Pattern-matching is, putting it simple, a way to define our functions by equations described by, on the left side, one element of our datatype (either Leaf or Node, in our case) and on the right side, the result value. I'd recommend you to learn more about pattern-matching here: pattern matching in Haskell
Hence, we start our function by its type, as you correctly guessed:
maxInt :: Tree -> Int
As we have seen earlier, we will use pattern-matching for this. What would be the first equation, that is, the first pattern-matching case for our function? The simplest tree we have given our datatype is Leaf value. So we start with:
maxInt (Leaf n) = n
Why n as a result? Because we don't have any other value than n in the tree and therefore it's the maximum.
What happens in a more complex case?
maxInt (Node n leftTree rightTree) = ...
Well... we can think that the maximum value for the tree (Node n leftTree rightTree) would be the maximum among n, the maximum value of leftTree and rightTree.
Would you be encouraged to write the second equation? I strongly recommend you to first read the chapter of the book I just linked above. Also, you might want to read about recursion in Haskell.
I'm very new to haskell and need to use a specific data type for a problem I am working on.
data Tree a = Leaf a | Node [Tree a]
deriving (Show, Eq)
So when I make an instance of this e.g Node[Leaf 1, Leaf2, Leaf 3] how do I access these? It won't let me use head or tail or indexing with !! .
You perform pattern matching. For example if you want the first child, you can use:
firstChild :: Tree a -> Maybe (Tree a)
firstChild (Node (h:_)) = Just h
firstChild _ = Nothing
Here we wrap the answer in a Maybe type, since it is possible that we process a Leaf x or a Node [], such that there is no first child.
Or we can for instance obtain the i-th item with:
iThChild :: Int -> Tree a -> Tree a
iThChild i (Node cs) = cs !! i
So here we unwrap the Node constructor, obtain the list of children cs, and then perform cs !! i to obtain the i-th child. Note however that (!!) :: [a] -> Int -> a is usually a bit of an anti-pattern: it is unsafe, since we have no guarantees that the list contains enough elements, and using length is an anti-pattern as well, since the list can have infinite length, so we can no do such bound check.
Usually if one writes algorithms in Haskell, one tends to make use of linear access, and write total functions: functions that always return something.
Assumption: I'm aware of the ADT libraries here. They're cool. Maybe they could be better.
There is a really interesting example of ADT's in Clojure here:
We define an ADT generator like this:
(defmacro data
[adt-name equals-sign & constructors]
`(do
(defn ~(symbol (str adt-name "?")) [~'obj]
(= ~(str adt-name) (adt-name ~'obj)))
~#(for [[type-name & fields]
(filter (partial not= '(|))
(partition-by (partial = '|) constructors))]
(apply (partial emit-constructor adt-name type-name)
fields))))
Given the Haskell example:
data Tree a = Empty
| Leaf a
| Node Tree Tree
Then we write the Clojure
(data Tree = Empty | Leaf value | Node left right)
Which is pretty cool.
Now I feel like there is something missing from matching up to the Haskell equivalent, but I can't quite put my finger on what it is.
My question is: What is required to implement an ADT in Clojure?
To implement ADT in clojure you're required to be brave and insistent.
For the missing parts - I don't know what are you missing, but I know what I am missing usually.
1) I want to authomatically get some foldX-function to perform conversion to Boehm encoding - a natural fold for this datatype.
This, however, will require you to have user to specify which fields must refer to object of same type (left and right in your case).
For instance, that function, written for your example type in haskell (God save the laziness!) will look like:
foldTree :: a -> (v -> a) -> (a -> a -> a) -> Tree v -> a
foldTree empty value node = go
where
go tree =
case tree of
Empty -> empty
Value v -> value v
Node l r -> node (go l) (go r)
This is done in Coq, as I know, and called "induction".
2) I want to see predicates like isEmpty for all the branches. Seriously. The only language providing them is Pyret.
3) For bonus points, I also want to have some ability to derive structural Equality, Ordering, to- and from-string conversion.
∞-1) To own my soul, you can also automatically generate lenses and prisms into all fields and branches accordingly.
∞) To prove your own strength, you can also generate ana-, para- and apomorphisms, since foldX is a already a catamorphism.
My Tree definition is
data Tree = Leaf Integer | Node Tree Tree
This is a binary tree, with only values at the leaves.
I am given following definition for balanced trees:
We say that a tree is balanced if the number of leaves in the left and right subtree of every node differs by at most one, with leaves themselves being trivially balanced.
I try to create a balanced tree as follows:
t :: Tree
t = Node (Node (Node (Leaf 1) (Leaf 2)) (Node(Leaf 3)(Leaf 4))) (Node (Node (Leaf 5) (Leaf 6)) (Node (Leaf 7) (Leaf 8)) )
Can you please let me know if t above is a balanced tree with values only at the leaves?
Another question, how do I create another tree with values only at the leaves and it is unbalanced as per above definition.
Thanks
Can you please let me know if t above is a balanced tree with values only at the leaves?
I can, but I won't. However, I hope I can guide you through the process of writing a function that will determine whether a given tree is balanced.
The following is certainly not the most efficient way to do it (see the bottom for a hint about that), but it is a very modular way. It's also a good example of the "computation by transformation" approach that functional programming (and especially lazy functional programming) encourages. It seems pretty clear to me that the first question to ask is "how many leaves descend from each node?" There's no way for us to write down the answers directly in the tree, but we can make a new tree that has the answers:
data CountedTree = CLeaf Integer | CNode Integer Tree Tree
Each node of a CountedTree has an integer field indicating how many leaves descend from it.
You should be able to write a function that reads off the total number of leaves from a CountedTree, whether it's a Leaf or a Node:
getSize :: CountedTree -> Integer
The next step is to determine whether a CountedTree is balanced. Here's a skeleton:
countedBalanced :: CountedTree -> Bool
countedBalanced CLeaf = ?
countedBalanced (CNode _ left right)
= ?? && ?? && getSize left == getSize right
I've left the first step for last: convert a Tree into a CountedTree:
countTree :: Tree -> CountedTree
And finally you can wrap it all up:
balanced :: Tree -> Bool
balanced t = ?? (?? t)
Now it turns out that you don't actually have to copy and annotate the tree to figure out whether or not it's balanced. You can do it much more directly. This is a much more efficient approach, but a somewhat less modular one. I'll give you the relevant types, and you can fill in the function.
-- The balance status of a tree. Either it's
-- unbalanced, or it's balanced and we store
-- its total number of leaves.
data Balance = Unbalanced | Balanced Integer
getBalance :: Tree -> Balance
Im trying to make a funciton which allows me to add a new value to a tree IF the value at the given path is equal to ND (no data), this was my first attempt.
It checks the value etc, but the problem, is i want to be able to print the modified tree with the new data. can any one give me any pointers? I have also tried making a second function that checks the path to see if its ok to add data, but im just lost to how to print out the modified tree?
As iuliux points out, your problem is that you are treating your BTree as though it were a mutable structure. Remember functions in haskell take arguments and return a value. That is all. So when you "map over" a list, or traverse a tree your function needs to return a new tree.
The code you have is traversing the recursive tree and only returning the last leaf. Imagine for now that the leaf at the end of the path will always be ND. This is what you want:
add :: a -> Path -> Btree a -> Btree a
add da xs ND = Data da
add _ [] _ = error "You should make sure this doesn't happen or handle it"
add da (x:xs) (Branch st st2) =
case x of
L -> Branch (add da xs st) st2
R -> Branch st (add da xs st2)
Notice how in your original code you discard the Branch you pattern match against, when what you need to do is return it "behind you" as it were.
Now, on to the issue of handling situations where the leaf you arrive it is not a ND constructor:
This type of problem is common in functional programming. How can you return your recursive data structure "as you go" when the final result depends on a leaf far down the tree?
One solution for the trickiest of cases is the Zipper, which is a data structure that lets you go up down and sideways as you please. For your case that would be overkill.
I would suggest you change your function to the following:
add :: a -> Path -> Btree a -> Maybe (Btree a)
which means at each level you must return a Maybe (Btree a). Then use the Functor instance of Maybe in your recursive calls. Notice:
fmap (+1) (Just 2) == Just 3
fmap (+1) (Nothing) == Nothing
You should try to puzzle out the implementation for yourself!
I'm no expert in Haskell, but functional programming only works with functions. So kind of anything is a function.
Now, your function takes some input and returns something, not modifing the input. You have to retain the returned tree somewhere and that will be your new tree, the one with inserted element in it
We really need to see the Path and Error data types to answer your question, but you can print out your trees using the IO Monad:
main :: IO()
main = do let b = Branch ND (Branch (Data 1) (Data 2))
let b1 = add 10 [L] b --actual call depends on definition of Path
(putStrLn . show) b1