Haskell вход и выход? - PullRequest
       14

Haskell вход и выход?

1 голос
/ 09 декабря 2011

У меня есть программа, которую я написал на Haskell, и все, кроме IO, работает.Предполагается, что IO выполняет следующие действия: - получает число от пользователя; - если это число положительное, считайте столько строк в список, затем возьмите число и созданный список и передайте его функции, которая будет возвращать выходные данные.- Если вместо этого это отрицательное число, прочитайте только следующую строку, возьмите число и эту строку и передайте их функции, которая возвращает другой вывод

, который я использовал "интерпретировать (unlines. Map program.lines) "немного кода для целей тестирования, но я не уверен, как заставить его обрабатывать многострочный ввод (особенно когда число строк не является постоянным)

Буду признателен за любую помощь

Ах да, и программа зацикливается

Подробнее: Сама программа обрабатывает квадродерево.Входные данные могут быть следующими: 8 00000000 00111111 00001111 00001111 00011111 00111100 00111000 В этом случае программа видит 8, размер изображения и строит соответствующее ему дерево квадрантов.Вывод довольно запутанный, но в основном он превращает его в текстовое представление структуры дерева квадрантов.

Текущая программа:

module Main where

main = interact (unlines . map program . lines) -- the IO here is bologna, as it doesn't do anything with the user input
--turns ones and zeros into easier to distinguish characters
replace 0 = '.'
replace 1 = '*'
program x = display (toArray 8 (t2)) -- just a test case to see if the important functions work, as well as a placeholder for real IO, hopefully
data Quadtree a = Tip | Node a (Quadtree a) (Quadtree a) (Quadtree a) (Quadtree a) -- the quadtree datastructure
leaf x = Node x Tip Tip Tip Tip -- saves some typing
-- this function takes a quadtree and returns a 2-dimensional list of binary digits to draw the picture
toArray a (Node x Tip Tip Tip Tip) = replicate a (replicate a x) 
toArray a (Node x b c d e) = (zipWith (++) (toArray (div a 2) b) (toArray (div a 2) c)) ++ (zipWith (++) (toArray (div a 2) d) (toArray (div a 2) e))
display x = unlines (map (map replace) x) -- gives a printable form of the two dimensional array
-- function that turns a number from base five
basefive x
    | x < 5 = x
    | x >= 5 = basefive (div x 5) * 10 + (mod x 5)
-- inserts into quadtree
insert [] (Node 0 Tip Tip Tip Tip) = Node 1 Tip Tip Tip Tip
insert (x:xs) (Node 0 Tip Tip Tip Tip)
    | x == '1' = Node 2 (insert xs (leaf 0)) (leaf 0) (leaf 0) (leaf 0)
    | x == '2' = Node 2 (leaf 0) (insert xs (leaf 0)) (leaf 0) (leaf 0)
    | x == '3' = Node 2 (leaf 0) (leaf 0) (insert xs (leaf 0)) (leaf 0)
    | x == '4' = Node 2 (leaf 0) (leaf 0) (leaf 0) (insert xs (leaf 0))
insert (x:xs) (Node a b c d e)
    | x == '1' = Node a (insert xs b) c d e
    | x == '2' = Node a b (insert xs c) d e
    | x == '3' = Node a b c (insert xs d) e
    | x == '4' = Node a b c d (insert xs e)
-- builds quadtree from scratch
insertall [] x = x
insertall (x:xs) y = insert x (insertall xs y)
s1 = "9 14 17 22 23 44 63 69 88 94 113" -- the example quadtree "path"; it represents the structure
s2 = ["00000000","00000000","00001111","00001111","00011111","00111111","00111100","00111000"] -- this represents the image
-- function which splits a list in half
split :: [a] -> ([a],[a])
split xs = go xs xs where
  go (x:xs) (_:_:zs) = (x:us,vs) where (us,vs)=go xs zs
  go    xs   _       = ([],xs)
quarter a b c = ((a . split) (map (b . split) c)) -- function which quarters a 2 dimensional list
-- function which takes a 2 dimensional array and returns its tree
toTree a x
    | x == replicate a (replicate a '1') = (leaf 1)
    | x == replicate a (replicate a '0') = (leaf 0)
    | otherwise = Node 2 (toTree (div a 2) (quarter fst fst x)) (toTree (div a 2) (quarter fst snd x)) (toTree (div a 2) (quarter snd fst x)) (toTree (div a 2) (quarter snd snd x))
t2 = toTree 8 s2

И s1, и s2 являются примерами пользовательских вводимых данных;случайные восьмерки - это размер изображения дерева квадрантов, которое также должен быть предоставлен пользователем

1 Ответ

4 голосов
/ 09 декабря 2011

Итак, у вас действительно есть спецификация для функции:

Получить число от пользователя - если это число положительное, прочитайте столько строк в список, затем возьмите число и создайтеперечислите и передайте его функции, которая будет возвращать вывод. Если это число вместо этого отрицательное, прочитайте только следующую строку, возьмите число и эту строку и передайте его функции, которая возвращает другой вывод.

Мы можем просто написать эту функцию напрямую.

interactiveFun f g = do
       let readInt :: String -> Int
           readInt = read
       x <- fmap readInt getLine
       if x > 0
           then print . f . map readInt =<< replicateM x getLine
           else print . g x . readInt =<< getLine

Edit : <$> - это тот же инфикс fmap, и происходит из Control.Applicative.Это идиоматичный Haskell, но я отредактировал его для простоты.replicateM исходит от Control.Monad.Вы должны импортировать и использовать его - многие повседневные функции Haskell поступают из базовых библиотек, отличных от Prelude.Все эти базовые библиотеки являются частью стандарта, являются переносимыми, полезными и должны использоваться свободно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...