Mushy-pea 36 What, you can change this tag?

Hi. I'm working on some Haskell code that takes some string input and processes it to return a list of integers, the reason for which should become clear when the app. eventually get finished. The list processing functions do what I want when I call "parse_data (contents)" in GHCi, but when I run the whole program they terminate early and only return the result of the first two characters of input.

-- These functions convert numbers between decimal, binary and hex bases and are used for encoding and decoding maze
-- descriptions

decimal_binary :: Float -> Float -> [Int]
decimal_binary d_num factor = if d_num < 0 || d_num > 255
                            then [0]
                            else if (d_num - factor) < 0
                              then 0 : decimal_binary d_num (factor / 2)
                            else if (d_num - factor) == 0
                              then [1]
                              else 1 : decimal_binary (d_num - factor) (factor / 2)

pad :: [Int] -> [Int]
pad xs = take 8 (xs ++ [0, 0, 0, 0, 0, 0, 0, 0])

binary_hex :: [Int] -> [Char]
binary_hex xs = (count1 (take 4 xs)) ++ (count1 (drop 4 xs))

count1 :: [Int] -> [Char]
count1 xs = case xs of
         [0, 0, 0, 0] -> "0"
         [0, 0, 0, 1] -> "1"
         [0, 0, 1, 0] -> "2"
         [0, 0, 1, 1] -> "3"
         [0, 1, 0, 0] -> "4"
         [0, 1, 0, 1] -> "5"
         [0, 1, 1, 0] -> "6"
         [0, 1, 1, 1] -> "7"
         [1, 0, 0, 0] -> "8"
         [1, 0, 0, 1] -> "9"
         [1, 0, 1, 0] -> "A"
         [1, 0, 1, 1] -> "B"
         [1, 1, 0, 0] -> "C"
         [1, 1, 0, 1] -> "D"
         [1, 1, 1, 0] -> "E"
         [1, 1, 1, 1] -> "F"

hex_decimal :: [Char] -> Int
hex_decimal xs = ((count2 (xs !! 0)) * 16) + (count2 (xs !! 1))

count2 :: Char -> Int
count2 '0' = 0
count2 '1' = 1
count2 '2' = 2
count2 '3' = 3
count2 '4' = 4
count2 '5' = 5
count2 '6' = 6
count2 '7' = 7
count2 '8' = 8
count2 '9' = 9
count2 'A' = 10
count2 'B' = 11
count2 'C' = 12
count2 'D' = 13
count2 'E' = 14
count2 'F' = 15
count2 _ = 1

-- Parse hex data from a file and pass to above functions for conversion to a binary structure

parse_data :: [Char] -> [Int]
parse_data [] = []
parse_data (x0:x1:x2:xs) = decimal_binary (fromIntegral (hex_decimal [x1, x2])) 128 ++ parse_data xs

main = do
  hSetBuffering stdin LineBuffering
  putStr "Please press ENTER to enter maze description manually or enter file name to load from file. : "
  answer <- getLine
  if answer /= "" then doGetMaze answer
    else do putStr "\nPlease enter maze description: "
            contents <- getLine
            print (parse_data contents)

doGetMaze filename = do
  bracket (openFile filename ReadMode) hClose
          (\h -> do contents <- hGetContents h
                    putStrLn ("Maze description: " ++ contents)
                    doShowMaze contents)

The input is of the form

 56 D0 09 FD 29 71 99 8E DE 62 11 3F DA 85 16 9F 5C 99 6D 14 97 EF 20 1B FF 00 3F 90

I just get out [01010110] compared to lines and lines of 1s and 0s when I call "parse_data" in GHCi. So, it's evidently an I/O issue and the same happens using stdin or file input. I've tried using other input functions like

        contents <- getContents
        print (parse_data (take 84 contents))

but then stdin doesn't seem to close and I'm not sure why, as the evaluation of "getContents" is supposed to be lazy and only the first 84 characters are passed to "parse_data" here. Could anyone suggest a way to simply pass a finite string to my function? Any advice would be appriciated.

Steven.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.