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.