Search code examples
haskellbinary-search-treetiming

timing experiment on bst in haskell


Hi i am trying to learn haskell and compare its performance to other languages when i run the following code..

module BST (
  Tree,
  singletonTree,
  insert,
  member
) where


import System.IO
import System.IO.Error hiding (try)
import Control.Exception
import Data.Char
import System.CPUTime


--
-- Take the string and convert it to a list of numbers
--
trim = f . f
   where f = reverse . dropWhile isSpace
fromDigits = foldl addDigit 0
       where addDigit num d = 10*num+d
strToInt str = fromDigits (map digitToInt str)
split_comma "" = []
split_comma input = 
        let (a,b) = break (\x->x==',') input in 
        [(trim a)]++(split_comma (drop 1 b))
make_int_list input =map strToInt (split_comma input)
-- end of converting string to integers




data Tree a = EmptyTree | Node a (Tree a)(Tree a) deriving (Show)

singletonTree :: a -> Tree a
singletonTree x = Node x EmptyTree EmptyTree

insert :: Ord a => a -> Tree a -> Tree a
insert x EmptyTree = singletonTree x
insert x (Node root left right) 
    | x < root = Node root (insert x left) (right)
    | x > root  = Node root (left) (insert x right)
    | x == root = Node root (Node x left EmptyTree) (right) 

member :: Ord a => a -> Tree a -> Bool
member x EmptyTree = False
member x (Node n left right)
  | x == n = True
  | x < n = member x left
  | x > n = member x right


---A test function to do the timing
test_func input_list =do
      startTime <- getCPUTime
      --Note: If you don't use any results haskell won't even run the code
      -- if you just mergesrt here (uncomment next line) instead of print
      -- return (let tree = foldr insert EmptyTree )
      -- then it will always take 0 seconds since it won't actually sort!
      let tree = foldr insert EmptyTree input_list
      prin(tree)
      finishTime <- getCPUTime
      return $ fromIntegral (finishTime - startTime) / 1000000000000

main :: IO ()
main = do 
       inh <- openFile "random_numbers.txt" ReadMode
       mainloop inh 
       hClose inh
--Read in my file and run test_func on input
mainloop :: Handle -> IO ()
mainloop inh  = 
    do input <- try (hGetLine inh)
       case input of
         Left e -> 
             if isEOFError e
                then return ()
                else ioError e
         Right inpStr ->
             do
        let my_list = make_int_list inpStr;
            my_time <- test_func my_list
                    putStrLn ("Execution time in Sections: ")
                         print(my_time);
                    return ();

when attempting to run this code i get

Prelude> :load "bst.hs" [1 of 1] Compiling BST ( bst.hs, interpreted )

bst.hs:83:29: parse error on input `<-' Failed, modules loaded: none.

i have exhausted my knowledge of haskell. I tried moving the module statements to both before and after the includes but neither help. I have used both the bst and the timing code separately but combined is causing error

random_numbers.txt is a list of comma separated values.


Solution

  • The last do block is not formatted correctly. Here is a diff:

    @@ -78,9 +78,7 @@
                     then return ()
                     else ioError e
              Right inpStr ->
    -             do
    -        let my_list = make_int_list inpStr;
    -            my_time <- test_func my_list
    -                    putStrLn ("Execution time in Sections: ")
    -                         print(my_time);
    -                    return ();
    +             do let my_list = make_int_list inpStr;
    +                my_time <- test_func my_list
    +                putStrLn("Execution time in Sections: ")
    +                print(my_time)
    

    Notes:

    • I am not using tabs anywhere in the source; I have a feeling your source uses tabs. My advice is to avoid tabs in Haskell source.
    • You do not need parens to call functions - putStrLn "..." and print my_time will work

    Also, prin(tree) earlier should be print(tree) but is more commonly written print tree - the parens are not needed.