功能相当于迭代2D数组

ext*_*ine 6 haskell functional-programming

我在Haskell中有这个功能(我使用的是Haskell-SDL库):

pixel :: Surface -> Int16 -> Int16 -> Pixel -> IO Bool

pixel screen x y color

我想使用它来获取2D数组(或其他类型的数据结构)并将其绘制到屏幕上,一次一个像素.我考虑过这样做,forM_但无法弄清楚如何让它对x和y参数进行操作.

我对Haskell和函数式编程很新.我正在通过Yet Another Haskell Tutorial工作,但这个问题让我感到难过.

如果它与解决方案相关,我正在尝试编写光线跟踪器.它必须对每个像素执行计算,然后将该像素写入屏幕.

Pau*_*son 2

您需要在这里拆分两个问题。首先您需要计算像素值。这应该是场景和您向其中发射的光线坐标的纯函数。然后您需要将该像素值写入屏幕。

所以首先你需要一个函数:

type Coord = (Int, Int)

raytrace :: Scene -> Coord -> (Coord, Colour)  
    -- You will see why it returns this pair in a few lines
Run Code Online (Sandbox Code Playgroud)

然后你想为表面上的每个像素调用该函数,以获取坐标颜色对的列表:

allCoords :: Int -> Int -> [Coord]
allCoords width height = [(x,y) | x <- [0..width], y <- [0..height]]

allPixels :: Scene -> Int -> Int -> [(Coord, Colour)]
allPixels scene w h = map (raytrace scene) (allCoords w h)
Run Code Online (Sandbox Code Playgroud)

最后使用“像素”函数将像素列表放到显示表面上。

writeScene :: Surface -> Scene -> Int -> Int -> IO ()
writeScene surface scene w h = mapM_ writePixel (allPixels scene w h)
    where writePixel ((x,y),c) = pixel surface x y c
Run Code Online (Sandbox Code Playgroud)

唯一的是,你的“pixel”函数返回一个“IO Bool”。我不知道为什么,所以我使用“mapM_”而不是“mapM”来忽略它。

这看起来像是构建了一个极其低效的坐标颜色对列表,然后迭代它来绘制图片。但事实上,由于 Haskell 的惰性,它实际上编译为一个生成每种颜色的循环,然后对结果调用“像素”。