如何将图像转换为颜色矩阵?

时间:2013-09-03 07:04:40

标签: haskell monads

我正在玩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”?

1 个答案:

答案 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,你只是向上传播它。