thank you very much Job. Regards, Kashyap On Thu Aug 20th, 2009 1:13 PM EDT Job Vranish wrote:
>Opps: >setPixel = State setPixel' > >should be: >setPixel x y rgb = State $ setPixel' x y rgb > >- Job > >On Thu, Aug 20, 2009 at 1:05 PM, Job Vranish <jvran...@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, >> 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 <ck_kash...@yahoo.com> wrote: >> >>> 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 >>> >>> >> _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe