# doing state right Classic List Threaded 5 messages Open this post in threaded view
|

## doing state right

 I am using a PPM library to generate a square image where each white pixel represents a prime number.  The PPM library takes a function (Int -> Int -> Colour) to create the image.  This interface isn't ideal but it is what I have to work with.  I am convinced that using a sieve is faster than testing every pixel in the image for primality, but the (Int -> Int -> Colour) interface makes this awkward.  The code below attempts to treat the list of prime numbers as a stack via global mutable state, popping the head whenever the pixel is prime. Obviously this is not idiomatic Haskell.  What is the correct approach of dealing with state here?  Thanks for reading. import ONeillPrimes import PPM6 import Colour import Data.IORef import System.IO.Unsafe limit = 2000 slimit = limit*limit primeList = takeWhile (<=slimit) primes p :: IORef [Int] p = unsafePerformIO (newIORef primeList) pcol n = unsafePerformIO \$ do     xs <- readIORef p     if null xs then return black else         if n == head xs             then do                 writeIORef p (tail xs)                 return white             else                 return black main = quick_ppm "foo.ppm" (\i j -> pcol ((i-1)*limit+j)) limit limit -- quick_ppm :: FilePath -> (Int -> Int -> Colour.Colour) -> Int -> Int -> IO ()
Open this post in threaded view
|

## doing state right

Open this post in threaded view
|

## doing state right

 In reply to this post by Floptical Logic On Thu, Apr 23, 2009 at 7:59 AM, Floptical Logic <[hidden email]> wrote: > I am using a PPM library to generate a square image where each white > pixel represents a prime number. ?The PPM library takes a function > (Int -> Int -> Colour) to create the image. ?This interface isn't > ideal but it is what I have to work with. ?I am convinced that using a > sieve is faster than testing every pixel in the image for primality, > but the (Int -> Int -> Colour) interface makes this awkward. Only because you're still not familiar with arrays in Haskell, this interface is absolutely not a problem : main = quick_ppm "foo.ppm" (\i j -> isPrime ((i-1)*limit+j)) limit limit   where     isPrime n = primeSieve ! n     primeSieve :: UArray Int Bool     primeSieve = accumArray (\_ _ -> True) False (0,limit*limit) \$ zip primes (repeat ()) There are in fact algorithms that would directly do the sieve on an array (the classical algorithm would do nicely) but if you don't need exceedingly good performance, that will do. -- Jeda?