Safe Haskell | None |
---|---|
Language | Haskell2010 |
Inclusion of files in source code via Template Haskell.
When distributing executables, sometimes it is required to attach some other resources in
files. Using includeFileInSource
you avoid this problem by including those files inside
the executable at compile time.
Example
A quick example. I want to include a small image (foo.png
) in the executable. I would do:
{-# LANGUAGE TemplateHaskell #-} import Development.IncludeFile $(includeFileInSource "foo.png" "myImage")
This defines the myImage
value with type ByteString
and with the content of the file foo.png
.
Using includeFileInSource
The following entities must be in scope when calling includeFileInSource
:
- A
ByteString
type. - A
Word8
type, instance of theNum
class (at least with thefromInteger
method implemented). - A
pack :: [Word8] -> ByteString
function.
This module re-export these for convenience, but you can use your own types (for example, using lazy bytestrings instead of strict bytestrings).
Using lazy bytestrings
To use lazy bytestrings, instead of importing this full module, import it like this:
import Data.ByteString.Lazy (ByteString,pack) import Development.IncludeFile (includeFileInSource,Word8)
Needless to say, if you have already imported any of those entities, you don't have to do it again.
Performance impact
Benchmarks confirm that it is much faster to use an included bytestring than reading it from a file.
benchmarking include-file time 1.814 ns (1.799 ns .. 1.826 ns) 1.000 R² (0.999 R² .. 1.000 R²) mean 1.808 ns (1.797 ns .. 1.819 ns) std dev 37.48 ps (31.27 ps .. 46.78 ps) benchmarking read-file time 4.869 μs (4.798 μs .. 4.938 μs) 0.998 R² (0.998 R² .. 0.999 R²) mean 4.911 μs (4.857 μs .. 4.968 μs) std dev 178.8 ns (150.1 ns .. 212.5 ns)
Large files
Do not use includeFileInSource
with large files. The limit between what is and what is not a large
file remains uncertain.
- includeFileInSource :: FilePath -> String -> Q [Dec]
- data ByteString :: *
- data Word8 :: *
- pack :: [Word8] -> ByteString
Including files
Define a value of type ByteString
(where ByteString
is whatever ByteString
type is in scope)
with the content of a file.
Convenient re-exports
data ByteString :: *
A space-efficient representation of a Word8
vector, supporting many
efficient operations.
A ByteString
contains 8-bit bytes, or by using the operations from
Data.ByteString.Char8 it can be interpreted as containing 8-bit
characters.
data Word8 :: *
8-bit unsigned integer type
pack :: [Word8] -> ByteString
O(n) Convert a '[Word8]' into a ByteString
.
For applications with large numbers of string literals, pack can be a bottleneck. In such cases, consider using packAddress (GHC only).