我正在玩Graphics.GD
,我想将图片读入Color
值的矩阵,有点像这样:
rectFromImage :: Image -> IO [[Color]]
rectFromImage img = do
size <- imageSize img
return [[getPixel (x,y) img | x <- [1 .. fst size]] | y <- [1 .. snd size]]
显然,这不起作用,因为getPixel
返回IO Color
,而不是Color
:
Couldn't match type `IO Color' with `Foreign.C.Types.CInt'
Expected type: Color
Actual type: IO Color
In the return type of a call of `getPixel'
In the expression: getPixel (x, y) img
In the expression: [getPixel (x, y) img | x <- [1 .. fst size]]
如何在getPixel
电话回复中“摆脱IO”?
答案 0 :(得分:4)
sequence
是您正在寻找的神奇功能。 sequence
获取IO操作列表并使其成为值的IO列表。在类型签名术语中:
sequence :: Monad m => [m a] -> m [a]
或者,更具体地说,在您的情况下:
sequence :: [IO a] -> IO [a]
所以你可以做,例如:
do
putStrLn "Enter three lines of input:"
irritatedUser <- sequence [getLine, getLine, getLine]
putStrLn (irritatedUser !! 2)
将打印用户所写的最后一行。
无论如何,在你的情况下,这意味着你想要做
rectFromImage img = do
size <- imageSize img
sequence [sequence [getPixel (x,y) img | x <- [1 .. fst size]] | y <- [1 .. snd size]]
我偷了两个sequence
来电,从你的[[IO Color]]
转到[IO [Color]]
然后转到IO [[Color]]
。
一般来说,你永远不会“摆脱”IO,你只是向上传播它。