
Your setPixel function is almost ready to work in a State monad
If you modify your setPixel function slightly like so:
setPixel' :: Int -> Int -> Color -> B.ByteString -> ((), B.ByteString)
setPixel' x y (r,g,b) image = ((), B.concat [beforePixel, pixel,
afterPixel])
and then wrap it in the State monad constructor:
setPixel = State setPixel'
then you can do
drawPixels = do
setPixel 5 10 (200, 0, 0)
setPixel 20 1 (0, 200, 0)
setPixel 90 2 (0, 0, 200)
modifiedImage = execState drawPixels originalImage
See! you were already using a monad and didn't even know it! :D
Performance wise, B.concat is O(n), which is very not good for your
purpose. It copies the whole string and the optimizer won't be able to
magically make it go away. For something that works in O(1), you will have
to use something like STArrays instead of bytestrings.
- Job
On Thu, Aug 20, 2009 at 2:32 AM, CK Kashyap
Hi, I had posted a note on line drawing algo with Haskell some time back. Now, I am trying to write a PNM image.
import qualified Data.ByteString as B
width = 256 height = 256 bytesInImage = width * height * 3 blankImage = B.pack $ take bytesInImage (repeat 0)
type Color = (Int,Int,Int) setPixel :: B.ByteString -> Int -> Int -> Color -> B.ByteString setPixel image x y (r,g,b) = B.concat [beforePixel, pixel, afterPixel] where beforePixel = B.take before image afterPixel = B.drop (before+3) image pixel=B.pack [(fromIntegral r),(fromIntegral g),(fromIntegral b)] -- number of bytes before the 3 bytes of -- the pixel at x y before = (y * width * 3) + (x * 3) - 3
main = do putStrLn "P6" putStrLn ( (show width) ++ " " ++ (show height) ) putStrLn "255" -- Set a red pixel at 100 100 B.putStr (setPixel blankImage 100 100 (255,0,0))
Can I please have some review comments on the code above? Would recreating the entire ByteString for each setPixel be an overhead? Also, I am barely beginning to grasp the Monad concept....I was wondering if there could be a monadic style of implementation of this - that could potentially have a series of setPixels inside a do block?
Regards, Kashyap
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe