Safe Haskell | None |
---|---|
Language | Haskell2010 |
Backend base module.
Defines the type of the backend and some useful functions.
Synopsis
- type Backend = MkFiles ()
- type MkFiles a = WriterT [GeneratedFile] IO a
- data GeneratedFile = GeneratedFile {}
- type MakeComment = String -> String
- execBackend :: MkFiles () -> IO [GeneratedFile]
- mkfile :: FileContent c => FilePath -> MakeComment -> c -> MkFiles ()
- liftIO :: MonadIO m => IO a -> m a
- writeFiles :: FilePath -> MkFiles () -> IO ()
Documentation
type MkFiles a = WriterT [GeneratedFile] IO a Source #
Define the type of the backend functions. For more purity, instead of having each backend writing the generated files to disk, they return a list of pairs containing the (relative) file path and the file content. This allow for 1) easier testing, 2) implement common options like changing the output dir or providing a diff instead of overwritting the files on a highter level and 3) more purity.
The writer monad provides a more convenient API to generate the list. Note
that we still use the IO
monad for now because some backends insist on
printing stuff to the screen while generating the files.
data GeneratedFile Source #
A result file of a backend.
GeneratedFile | |
|
Instances
Eq GeneratedFile Source # | |
Defined in BNFC.Backend.Base (==) :: GeneratedFile -> GeneratedFile -> Bool # (/=) :: GeneratedFile -> GeneratedFile -> Bool # | |
Show GeneratedFile Source # | |
Defined in BNFC.Backend.Base showsPrec :: Int -> GeneratedFile -> ShowS # show :: GeneratedFile -> String # showList :: [GeneratedFile] -> ShowS # |
type MakeComment = String -> String Source #
Type of comment-generating functions.
execBackend :: MkFiles () -> IO [GeneratedFile] Source #
Named after execWriter, this function execute the given backend and returns the generated file paths and contents.
mkfile :: FileContent c => FilePath -> MakeComment -> c -> MkFiles () Source #
A specialized version of tell
that adds a file and its content to the
list of generated files.
liftIO :: MonadIO m => IO a -> m a #
Lift a computation from the IO
monad.
This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations
(i.e. IO
is the base monad for the stack).
Example
import Control.Monad.Trans.State -- from the "transformers" library printState :: Show s => StateT s IO () printState = do state <- get liftIO $ print state
Had we omitted
, we would have ended up with this error:liftIO
• Couldn't match type ‘IO’ with ‘StateT s IO’ Expected type: StateT s IO () Actual type: IO ()
The important part here is the mismatch between StateT s IO ()
and
.IO
()
Luckily, we know of a function that takes an
and returns an IO
a(m a)
:
,
enabling us to run the program and see the expected results:liftIO
> evalStateT printState "hello" "hello" > evalStateT printState 3 3
writeFiles :: FilePath -> MkFiles () -> IO () Source #
Write a set of files to disk. the first argument is the root directory
inside which all the generated files will be written. This root directory
and sub-directories will be created as needed (ex: if the files contains a
a/b/file.txt
, writeFiles
will create the directories $ROOT/a
and
$ROOT/a/b
)