简体   繁体   English

如何在 zip 生成的列表上折叠 io 操作以打印 2 列?

[英]How to foldl an io operation on a list generated by a zip in order to print 2 columns?

I have seen several questions regard to use of foldl and IO but none of them seem to provide a solution to my case.我已经看到了几个关于使用 foldl 和 IO 的问题,但它们似乎都没有为我的案例提供解决方案。

I am simply trying to output two columns of numbers.我只是想 output 两列数字。

0 256
1 256
2 256
...
256 256
0 255
1 255
2 255
3 255
4 255

I have tried the following but I was only able to print a single line and not an entire column:我尝试了以下方法,但我只能打印一行而不是一整列:

zipMerge :: [a] -> [b] -> [(a,b)]
zipMerge [] _      = []
zipMerge _  []     = error "second list cannot be empty"
zipMerge (a:as) bs = (zip (replicate (length bs) a) bs) ++ (zipMerge as bs)

-- foldl :: (a -> b -> a) -> a -> [b] -> a
printPixel :: IO() -> (Int, Int) -> IO()
printPixel _ (i, j) = putStrLn (show i) ++ " " ++ (show j)

printPixels :: [(Int, Int)] -> IO()
printPixels colors = foldl printPixel (return ()) colors

printGradient :: IO()
printGradient = do
    putStrLn "255"
    let is = [0..256]
        js = [256,255..0]
    printPixels (zipMerge js is)

What am I doing wrong?我究竟做错了什么?

A fold is definitely overkill here.弃牌在这里绝对是矫枉过正。 The idea of fold is to keep some sort of state as you traverse the list, but in your case there is no state to keep: you just need to perform an effect for every element in order, and independently of other elements. fold 的想法是在遍历列表时保留某种 state ,但在您的情况下,没有要保留的 state :您只需要按顺序为每个元素执行效果,并且独立于其他元素。

To do this, use mapM_ :为此,请使用mapM_

printPixel :: (Int, Int) -> IO()
printPixel (i, j) = putStrLn $ (show i) ++ " " ++ (show j)

printPixels :: [(Int, Int)] -> IO()
printPixels colors = mapM_ printPixel colors

Or its twin for_ , which is the same thing, but with arguments in reverse order (and weaker constraints), which lets you provide the effect as a lambda-expression, but without parentheses, making it look almost like the for constructs in C-like languages:或者它的双胞胎for_ ,这是同一件事,但 arguments 的顺序相反(和较弱的约束),这使您可以将效果作为 lambda 表达式提供,但没有括号,使其看起来几乎像 C 中的for构造-喜欢语言:

printPixels :: [(Int, Int)] -> IO()
printPixels colors = for_ colors $ \(i, j) -> putStrLn $ (show i) ++ " " ++ (show j)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM