Compiling in constants

From HaskellWiki
Revision as of 22:26, 3 March 2008 by DonStewart (talk | contribs) (data stored in C example)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

An example where a data structure constant is compiled into the source. To avoid excessive compilation time, we pack the structure into a bytestring literal (and gzip it for fun).

{-# LANGUAGE OverloadedStrings #-}

import Data.Binary
import qualified Data.Map as M
import qualified Data.ByteString.Char8 as S
import Data.ByteString.Lazy
import Codec.Compression.GZip

--
-- this is a gzip compressed literal bytestring, storing a binary-encoded Data.Map
--
mytable =
    "\US\139\b\NUL\NUL\NUL\NUL\NUL\NUL\ETXEN\
    \\219\SO\194 \f\197\224\188\196\CAN\227\US\
    \\224\171~\NAKc\GS4ce\161`\178\191\215(\176\
    \\190\180\167\231\210\n\241\171\203\191\ti\
    \\157\217\149\249< \ENQ\214\&9>\202\162\179a\
    \\132X\233\ESC=\231\215\164\SYN\157\DC2D\226*\
    \\146\174o\t\167\DLE\209\"i_\240\193\129\199<W\
    \\250nC\CAN\212\CAN\162J\160\141C\178\133\216;\
    \\\@4\144-W\203\209x\205\140\166\RS\163\237]9f\
    \\170\143\ACK\163g\223\STX\184\&7\rH\222\FSW\
    \\130\&7D\197\NUL\164\&0U\193\186\t\186o\
    \\228\180~\NUL\a6\249\137#\SOH\NUL\NUL"

main = print =<< M.lookup "ghc" m
    where
        -- build the table from the bytestring:
        m :: M.Map String (Maybe String)
        m = decode . decompress . fromChunks . return $ mytable

Running this:

    $ ./A
    Just "dinosaur!"

Storing the structure in C

For very large constant data, its more efficient to bypass the Haskell frontend, and store the structure in C code.

In this case, we'd take the compressed encoded structure, translate it to a C array type, then access it as a Ptr Word8 from Haskell. That Word8 Ptr can be used to build a bytestring, which can in turn be rehydrated via Data.Binary.

A full example is here: http://code.haskell.org/~dons/code/compiled-constants