3

我正在玩,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]]

在调用返回时如何“摆脱 IO” getPixel

4

1 回答 1

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电话,从 your[[IO Color]]转到 an [IO [Color]],然后转到 an IO [[Color]]

一般来说,你永远不会“摆脱” IO,你只是向上传播它。

于 2013-09-03T07:13:29.733 回答