The Haskell State Preprocessor
It is lightweight in the sense that it performs no syntactic analysis and is essentially a character transformer. As such, it is limited in some areas, but not significantly. If I find people actually use this, I may be inclined to make it more robost (email me at if you find it useful).
The basic idea is to allow notation in Haskell similar to the standard array[x][y] notation from C/Java/etc. Since brackets are already used by Haskell for lists, we use barred-brackets, so the above would be written array[|x|][|y|].
STPP supports three (or four, depending on how you count) operations: read, assign, update (and use, which is basically read). Since all operations on stateful arrays occur in monads, we use exclusively the "do" notation. You can sort-of use explicit >>= notation, but at your own peril; most of STPP requires the existence of a <- token.
Furthermore, STPP functions must appear on one line completely and there really shouldn't be any trailing things (for instance, a close parenthesis and list for mapM, etc., should go on the next line).
z <- array[|x|][|y|]This assumes that array has type XArray t1 (XArray t2 t3) where XArray is a valid Array instance. Furthermore, x should have type t1 and y should have type t2. The desugaring converts this to:
y <- readArray array (x) >>= (flip readArray) (y) >>= return
array[|x|][|y|] <- exprWhere the type of array, x and y are as above and expr is of type t3, where m is the monad holding the state of array. This gets translated to:
return expr >>= \stpp_value -> readArray array (x) >>= \stpp_arr -> writeArray stpp_arr (y) stpp_valueMonadic assign operations appear as:
array[|x|][|y|] <<- exprWhere the type of array, x and y are as above and expr is of type m t3, where m is the monad holding the state of array. This gets translated to:
expr >>= \stpp_value -> readArray array (x) >>= \stpp_arr -> writeArray stpp_arr (y) stpp_value
array[|x|][|y|] <-$ exprThis means basically to apply expr to whatever is held in that location of array. The type of expr must be t3 -> m t3, again a monadic operation. This gets desugared into:
readArray array (x) >>= \stpp_arr -> readArray stpp_arr (y) >>= expr >>= writeArray stpp_arr (y)
array[|x|][|y|] >>= printAnd are semantically the same as read operations, but they don't require the <- token. This gets translated to:
readArray (array) (x) >>= (flip readArray) (y) >>= print
eof <- isEOF h if eof then ...We can make this shorting using the mif construct:
mif isEOF h then ...Finally, monadic case expressions alleviate expressions like:
exists <- ifFileExistsReadIt filepath case exists of Nothing -> ... Just txt -> ...and replace them with:
mcase ifFileExistsReadIt filepath of Nothing -> ... Just txt -> ...
module Main where import Data.Array.IO main = do (arr :: IOArray Int Int) <- newArray (0,4) 0 arr[|0|] <- return 5 arr[|1|] <- return 4 y <- arr[|0|] + 3 arr[|2|] <-$ return . (+5) arr[|3|] <- return (y * 2) arr[|4|] <- 2 * arr[|0|] + 3 getAssocs arr >>= printOr, even like this:
module Main where import Data.Array.IO main = do (arr :: IOArray Int (IOArray Int (IOArray Int Int))) <- newArray_ (0,4) mapM (\i -> do arr[|i|] <- newArray_ (0,4) mapM (\j -> do arr[|i|][|j|] <- newArray (0,4) 0 ) [0..4]) [0..4] arr[|0|][|1|][|0|] <-$ return . (+1) arr[|0|][|1|][|1|] <-$ return . (+2) arr[|0|][|1|][|2|] <-$ return . (+3) arr[|0|][|1|][|3|] <-$ return . (+4) arr[|0|][|1|][|0|] >>= print arr[|0|][|1|][|1|] >>= print arr[|0|][|1|][|2|] >>= print arr[|0|][|1|][|3|] >>= printYou can see in this last program that ") [0..4]) [0..4]" had to go on its own line to avoid confusing the preprocessor.
% ghc --make STPP.hs -o stpp ghc-5.04: chasing modules from: STPP.hs Compiling Main ( STPP.hs, ./STPP.o ) ghc: linking ...Now, to use it:
% ghc --make -pgmF stpp -F -fglasgow-exts TryAPP.hs -o tryAPP ghc-5.04: chasing modules from: TryAPP.hs Compiling Main ( TryAPP.hs, ./TryAPP.o ) ghc: linking ... % ./tryAPP [(0,5),(1,4),(2,5),(3,16),(4,13)]You can download a compressed archive containing the STPP application and two sample programs here: stpp.tar.gz. For questions/comments/whatever (if you find it useful), email me at .