2011-12-09 80 views
1

我有一个程序,我已经写在Haskell,除了IO的一切工作。 IO意味着执行以下操作: - 从用户处获取一个数字 - 如果该数字是正数,则将该多行读入列表中,然后获取该数字并创建列表并将其传递给函数,该函数将返回输出 - 如果这个数字是负数,只能读取下一行,并将该数字和该行并将其传递给一个返回其他输出的函数Haskell输入和输出?

我一直在使用“interpret(unlines。map程序行“)代码的测试目的,但我不知道如何使它处理多行输入(特别是当行数不恒定时)

我将不胜感激任何帮助

稀释是,然后程序

更多细节: 本身处理四叉树程序。 输入可以是沿着这一行: 在这种情况下,程序看到图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都是样品的用户输入;各地抛出的随机八分是四叉树的形象,这应该也可以由用户

+0

您目前是否在使用任何IO,或者只是从GHCi运行纯函数?此外,它看起来像你期待更加均匀地处理所有输入行,而不是真正有意义;你需要以这种或那种方式迭代输入列表。虽然没有更多的代码,但很难确定你在做什么。 –

+0

我现在可能不会使用IO。我觉得发布任何代码都可能会削弱主要问题,但整个程序应该处理四叉树。如果用户输入一个正数,这意味着他们将要放入一张二进制数字的四叉树图像,并且他们放入的数字就是大小。我将编辑这个问题。 – user1006042

+0

但是IO代码是我们需要帮助您编写好的IO代码的。 –

回答

4

提供让您真正拥有一个功能规格的大小:在许多

采取从用户 - 如果这个数字是正数,则将多行读入列表中,然后获取数字并创建列表并将其传递给将返回输出的函数 - 如果此数字为负数,则只读取下一行,并取数字和该行,并将其传递给返回其他输出的函数。

我们可以直接写这个函数。

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 

编辑<$>是一样的中缀fmap,以及来自Control.Applicative。它的惯用的Haskell,但我为了简单而编辑它。 replicateM来自Control.Monad。您应该导入并使用它 - 许多日常Haskell函数来自基础库,而不是Prelude。所有这些基础库都是标准的一部分,是可移植的,有用的,应该宽松地使用。

+0

我看到一个我以前得到的错误。 “输入解析错误'='”?它指的是readInt =读取部分 – user1006042

+0

@ user1006042可能是错误的缩进,你是否将'r'与签名和定义对齐? –

+0

啊,是的,谢谢。从命令来看,缩进可能会让我经常遇到。可能最后一件事,<$>和replicateM是什么?我不认识他们,我的编译器似乎也没有。如果我必须导入任何东西,我宁愿尽量避免使用 – user1006042