我有一个我用Haskell编写的程序,除了IO之外的所有东西都在工作。 IO旨在执行以下操作: - 从用户那里接收一个号码 - 如果此数字为正数,请将多行读入列表,然后获取数字并创建列表并将其传递给将返回输出的函数 - 如果此数字为负数,则仅读取下一行,并取数字和该行并将其传递给返回其他输出的函数
我一直在使用“解释(unlines。地图程序。行)”代码来进行测试,但我不知道如何让它处理多行输入(特别是当行数没有时)常数)
我将不胜感激任何帮助
啊,是的,程序循环
更多细节: 程序本身处理四叉树。 输入可以是这样的: 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都是样本用户输入;抛出的随机八个是四叉树图像的大小,它应该也是由用户提供的
答案 0 :(得分: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
之外的基本库。所有这些基础库都是标准的一部分,可移植,有用,应该大量使用。