Expressiveness of Haskell

Tree traversal in Haskell, Python, and Java

My goto answer when someone asks why I like Haskell so much these days is usually “I like the expressiveness and run time guarantees of Haskell”. For those who are little more interested, I would usually show the popular quick sort or merge sort implementations. I wanted a slightly more complicated, yet commonly known, example to demonstrate what I claimed. This is an attempt at coming up with such an example. And turning it into a blog post makes it available for me all the time (and for other too!!).

I choose Python and Java as other two languages as they are the ones I am fairly comfortable with and also because they are representatives of objected oriented and dynamically typed languages. I do not claim mastery over any of these languages. If you have any suggestions on making any of the these implementations more expressive, let me know and I will update the sample accordingly. Other languages are welcome too!

Edit: Here is my take on what expressiveness mean

All three versions do the same thing. Define a simple Tree type. Instead of constructing the tree one-element-at-a-time, we provide a convenient function fromList which takes a list and adds its elements to tree. We also provide a way to turn the Tree back to a list by providing inorder function to traverse the tree in-order

The tree construction happens like this: we split the list in to three parts - middle element, left-sublist and right-sublist. Then, we recursively construct left and right sub-tree with the two split parts of the list. The middle element is used at the current node. Why we do it this way? If you pass a sorted list, this will construct a binary search tree. In-order traversal on that tree should return the original sorted list back!

Haskell

data Tree a = Empty | Node (Tree a) a (Tree a)
deriving (Show)
fromList :: [a] -> Tree a
fromList xs
| null xs = Empty
| otherwise = Node (fromList x1) x (fromList x2)
where (x1, x:x2) = splitAt (length xs `div` 2) xs
inorder :: Tree a -> [a]
inorder Empty = []
inorder (Node l x r) = inorder l ++ [x] ++ inorder r
view raw Tree.hs hosted with ❤ by GitHub

Python

class Tree(object):
def __init__(self, l, r, d):
self.left = l
self.right = r
self.data = d
def __str__(self):
s = "("
s += str(self.left) if self.left else " Empty "
s += " " + str(self.data) + " "
s += str(self.right) if self.right else " Empty "
s += ")"
return s
def inorder(self):
l = self.left.inorder() if self.left else []
l += [self.data]
l += self.right.inorder() if self.right else []
return l
@staticmethod
def fromList(items):
if not items:
return None
(l, r) = splitAt(len(items)/2, items)
return Tree(Tree.fromList(l), Tree.fromList(r[1:]), r[0])
def splitAt(n, items):
return (items[:n], items[n:])
view raw Tree.py hosted with ❤ by GitHub

Java

import java.lang.StringBuilder;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
class Tree<T> {
private Tree<T> left;
private Tree<T> right;
private T data;
public Tree(Tree<T> l, Tree<T> r, T d) {
this.left = l;
this.right = r;
this.data = d;
}
public String toString() {
StringBuilder sb = new StringBuilder("(");
sb.append(left == null ? " Empty " : left.toString());
sb.append(" " + data.toString() + " ");
sb.append(right == null ? " Empty " : right.toString());
sb.append(")");
return sb.toString();
}
public static <T> Tree fromList(List<T> items) {
if(items.isEmpty())
return null;
int len = items.size();
int mid = len / 2;
List<T> l = items.subList(0, mid);
List<T> r = items.subList(mid+1, len);
T x = items.get(mid);
return new Tree(fromList(l), fromList(r), x);
}
public List<T> inorder() {
List<T> list = new ArrayList();
list.addAll( left != null ? left.inorder() : new ArrayList());
list.add(data);
list.addAll( right != null ? right.inorder() : new ArrayList());
return list;
}
public static void main(String[] args) {
Integer [] array = {1,2,3,4,5};
List<Integer> list = Arrays.asList(array);
Tree<Integer> tree = Tree.fromList(list);
System.out.println(tree);
System.out.println(tree.inorder());
}
}
view raw Tree.java hosted with ❤ by GitHub

Related Articles