[Haskell-cafe] Right way to implement setPixel function
jvranish at gmail.com
Thu Aug 20 13:13:40 EDT 2009
setPixel = State setPixel'
setPixel x y rgb = State $ setPixel' x y rgb
On Thu, Aug 20, 2009 at 1:05 PM, Job Vranish <jvranish at gmail.com> wrote:
> 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,
> 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 <ck_kashyap at yahoo.com> wrote:
>> 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]
>> 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?
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe