Last active
September 7, 2017 05:08
-
-
Save ckoparkar/3e3c40195b9ada88adb7 to your computer and use it in GitHub Desktop.
Implementation of Binary Search Tree in Elm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{----------------------------------------------------------------- | |
A "Tree" represents a binary tree. A "Node" in a binary tree | |
always has two children. A tree can also be "Empty". Below I have | |
defined "Tree" and a number of useful functions. | |
This example also includes some challenge problems :) | |
-----------------------------------------------------------------} | |
import Graphics.Element exposing (..) | |
import Text | |
type Tree a | |
= Empty | |
| Node a (Tree a) (Tree a) | |
empty : Tree a | |
empty = | |
Empty | |
singleton : a -> Tree a | |
singleton v = | |
Node v Empty Empty | |
insert : comparable -> Tree comparable -> Tree comparable | |
insert x tree = | |
case tree of | |
Empty -> | |
singleton x | |
Node y left right -> | |
if x > y then | |
Node y left (insert x right) | |
else if x < y then | |
Node y (insert x left) right | |
else | |
tree | |
fromList : List comparable -> Tree comparable | |
fromList xs = | |
List.foldl insert empty xs | |
depth : Tree a -> Int | |
depth tree = | |
case tree of | |
Empty -> 0 | |
Node v left right -> | |
1 + max (depth left) (depth right) | |
map : (a -> b) -> Tree a -> Tree b | |
map f tree = | |
case tree of | |
Empty -> Empty | |
Node v left right -> | |
Node (f v) (map f left) (map f right) | |
t1 = fromList [1,2,3] | |
t2 = fromList [2,7,5] | |
main : Element | |
main = | |
flow down | |
[ display "depth" depth t1 | |
, display "depth" depth t2 | |
, display "map ((+)1)" (map ((+)1)) t2 | |
, display "sum" sum t2 | |
, display "flatten" flatten t2 | |
, display "isElement" (isElement 7) t2 | |
, display "sum with fold" (fold (+) 0) t2 | |
, display "flatten with fold" (fold (::) []) t2 | |
--, display "isElement with fold" (fold ((==) >> (||)) False) t2 | |
, display "map with fold" (map' ((+)1)) t2 | |
, display "depth with fold" depth' t2 | |
] | |
map' : (a -> comparable) -> Tree a -> Tree comparable | |
map' f tree = fold (\x xs -> insert (f x) xs) empty tree | |
depth' : Tree a -> Int | |
depth' = fold (\x n -> 1 + n) 0 | |
display : String -> (Tree a -> b) -> Tree a -> Element | |
display name f value = | |
name ++ " (" ++ toString value ++ ") ⇒\n " ++ toString (f value) ++ "\n " | |
|> Text.fromString | |
|> Text.monospace | |
|> leftAligned | |
sum : Tree number -> number | |
sum tree = | |
case tree of | |
Empty -> 0 | |
Node x left right -> | |
x + sum left + sum right | |
flatten : Tree a -> List a | |
flatten tree = | |
case tree of | |
Empty -> [] | |
Node x left right -> | |
flatten left ++ [x] ++ flatten right | |
isElement : comparable -> Tree comparable -> Bool | |
isElement a tree = | |
case tree of | |
Empty -> False | |
Node x left right -> | |
if x == a then | |
True | |
else if a > x then | |
isElement a right | |
else | |
isElement a left | |
fold : (a -> b -> b) -> b -> Tree a -> b | |
fold fn base tree = | |
let | |
xs = flatten tree | |
fold' f v ys = | |
case ys of | |
[] -> base | |
(y::ys) -> f y (fold' f v ys) | |
in | |
fold' fn base xs | |
{----------------------------------------------------------------- | |
Exercises: | |
(1) Sum all of the elements of a tree. | |
sum : Tree number -> number | |
(2) Flatten a tree into a list. | |
flatten : Tree a -> List a | |
(3) Check to see if an element is in a given tree. | |
isElement : a -> Tree a -> Bool | |
(4) Write a general fold function that acts on trees. The fold | |
function does not need to guarantee a particular order of | |
traversal. | |
fold : (a -> b -> b) -> b -> Tree a -> b | |
(5) Use "fold" to do exercises 1-3 in one line each. The best | |
readable versions I have come up have the following length | |
in characters including spaces and function name: | |
sum: 16 | |
flatten: 21 | |
isElement: 46 | |
See if you can match or beat me! Don't forget about currying | |
and partial application! | |
(6) Can "fold" be used to implement "map" or "depth"? | |
(7) Try experimenting with different ways to traverse a | |
tree: pre-order, in-order, post-order, depth-first, etc. | |
More info at: http://en.wikipedia.org/wiki/Tree_traversal | |
-----------------------------------------------------------------} |
@avinashsmiles, the following comes without testing, but consider:
your code: fold f (fold f (f b n) left) right
should be: fold f (fold f (f n b) left) right
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I've started learning elm recently mostly by reading docs and going through examples.
When I am attempting to solve binary tree challenges here http://elm-lang.org/examples/binary-tree , I am getting some weird errors. I thought I was doing something wrong.
I am running into two issues
I am using Elm-make version 0.16 in my PC, running the code in my PC and on online editor gives me the same errors.
However I am perfectly able to run your code. The only difference I see is in your fold function you are flattening the tree to a list and folding over the list instead of folding over the tree directly.
Is it the only way to do it? Why cant I directly fold over the tree?
Sorry for the long comment.
Thank you