GHC -ddump-splices option — Template Haskell - haskell

I'm following the Yesod book, which states:
But by using the -ddump-splices GHC option, we can get an immediate
look at the generated code. A much cleaned up version of it is:
How would I do this? I've tried compiling my file with ghc -XTemplateHaskell -ddump-splices Page.hs, which leaves the directory as follows:
Page Page.hi Page.hs Page.hs~ Page.o
None of these files, however, contain the intermediate code generated by Template Haskell.
http://www.yesodweb.com/book/basics

Meanwhile the behaviour changed and the -ddump-to-file flag in addition to the -ddump-splices flag causes the splices to be written to a file, see Section 9.26 of the current (GHC 8.2.1) documentation for more details.
On older versions of GHC (I didn't check in which version exactly the behaviour changed), -ddump-splices worked differently:
The -ddump-splices option causes GHC to dump the splices to stderr. Unfortunately, the -ddump-to-file flag doesn't affect splices (I don't know whether that has deeper reasons or is just an oversight), so you need to capture the stderr output to save the splices for later investigation,
ghc -XTemplateHaskell -ddump-splices Page.hs 2> Page.dump-splices
on sufficiently bash-like shells.

In large projects doing this for all modules is problematic.
Fortunately, you can dump per module.
This also works in ghci.
You can add this line to the top of your module
{-# OPTIONS_GHC -ddump-splices #-}
It dumps it to stderr.
{-# OPTIONS_GHC -ddump-to-file #-}
is also usefull which puts the dump in a file next to the module with the prefix .dump-simpl.
See reference: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/debugging.html#ghc-flag--ddump-to-file
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/debugging.html#ghc-flag--ddump-splices
You can add these as separate lines (for easy copy pasting)

Related

Turn off certain hlint rules in vscode

I have the following Visual Studio Code extensions for Haskell installed:
If I use elem in a prefix form:
(elem n primes)
I get a blue squiggly that suggests the infix form:
Is there a way to turn off just this particular hlint rule, hlint(refact:Use infix) just for this file or project?
Yes!
For a single source file, add one of these to the top of the file:
{-# ANN module "HLint: ignore Use infix" #-}
{-# HLINT ignore "Use infix" #-}
{- HLINT ignore "Use infix" -}
For the entire project, create a file .hlint.yaml as follows:
- ignore: {name: Use infix}
You can also run hlint --default > .hlint.yaml from a terminal, which will create a .hlint.yaml file ignoring any hints currently uncorrected in your project.
These are not VS Code specific - they apply wherever hlint is used.
For more information see the HLint manual.
Happy Haskelling!

But by using the -ddump-splices GHC option

I am learning yesod and would like to know, which code is generated behind, when I am using
mkYesod "HelloWorld" [parseRoutes|
/ HomeR GET
|]
function.
In the doc, it says:
We’ll look at this in more detail in the routing chapter. But by using
the -ddump-splices GHC option, we can get an immediate look at the
generated code.
How can I pass -ddump-splices to GHC option?
I start the application with:
stack runghc -ddump-splices helloworld.hs
I think you can use the OPTIONS_GHC pragma:
simply add
{-# OPTIONS_GHC -ddump-splices #-}
at the top of your file.
I don't see a way to pass options through to GHC when using stack runghc. You can compile your project with stack build, which accepts more options. The full command is stack build --ghc-options '-ddump-splices'.
After compiling, you may also want to run your project. If you followed the Yesod quickstart, I think stack exec -- yesod devel will work.
I ran across this today when working through the Yesod Book. The following seems to work well. Any option passed before -- is passed to stack and options after -- are passed directly to GHC
stack runghc -- -ddump-splices helloworld.hs

Enable package-wide extensions in "stack runghc"

If I have the following in my package.yaml file:
default-extensions:
- LambdaCase
I am able to compile my project which makes use of the LambdaCase syntax like this:
myFunction = \case
Nothing -> "empty"
Just x -> x
However, if the project is run with stack runghc, the LambdaCase extension is not respected.
My project has about 200 modules, so I would rather not have to add {-# LANGUAGE LambdaCase #-} to the top of every file.
Is there a way to enable a project-wide GHC extension with stack runghc analogously to the package-wide default-extensions property in package.yaml?
Yes, stack should probably have some better support for this -
see https://github.com/commercialhaskell/stack/issues/3338 .
I'd say the summary is that stack runghc came before stack ghci, it's ended up having a much simpler meaning that does not take cabal files into account at all. Not sure how to make things consistent and intuitive on the commandline without changing the meaning of runghc.
In that issue, I describe a hacky workaround. Copying it here:
Here's a workaround for now. Put the following in ~/.local/bin/stack-run-ghc.sh and make it user executable:
#/bin/sh
ghc $(echo "$*" | sed 's/--interactive//g')
This takes the arguments, removes --interactive, and calls ghc. With this, I can build stack using ghc via the following:
stack ghci --with-ghc stack-run-ghc.sh --ghci-options src/main/Main.hs

How can I load optimized code in GHCI?

I am writing a module that relies on optimization. I want to test this module in ghci. But starting ghc in --interactive mode automatically disables optimization; if I compile the module with -O and then try to load it in an interactive session, ghc insists on loading it in interpreted mode.
For a simple test case to distinguish optimized and unoptimized modules, isOptimized below evaluates to True with optimization on, but False with optimization off:
isOptimized :: Bool
isOptimized = g
g :: Bool
g = False
{-# NOINLINE g #-}
{-# RULES "g/True" g = True #-}
Either use ghci -fobject-code -O Test.hs or cabal repl --ghc-options="-fobject-code -O". In more detail:
ghci must be invoked with the -fobject-code flag.
Optimization flag(s) must be given after -fobject-code on the command line, or in an OPTIONS_GHC pragma at the top of the module. Trying ghc --interactive -O -fobject-code produces a warning that "-O conflicts with --interactive; -O ignored." This is perhaps a bug.
If you're working on a cabalized project and using cabal repl, you need to pass the flags either on the command line (i.e. cabal repl --ghc-options="-fobject-code -O") or in a pragma. Cabal (currently) discards optimization flags set in the .cabal file with ghc-options when invoking ghci; in fact, it explicitly sets -O0 instead. This is perhaps a bug.
Note in any case that you sometimes need to force recompilation manually when switching between optimized and unoptimized mode. Build artifacts are, for some reason, not invalidated when the optimization flags change so long as -fobject-code remains on. If, starting from a clean slate, you have -fobject-code set in your .cabal file, run cabal repl which compiles the module, and then remember you need to set -O on the command line and run cabal repl --ghc-options=-O, ghc will happily load the previously-compiled, unoptimized module. This is also perhaps a bug.
The most reliable scenario for testing a single module seems to be to put {-# OPTIONS_GHC -fobject-code -O #-} at the top of the module. You will get optimized code no matter how you invoke ghci. I haven't investigated what happens in multi-module situations where some but not all modules have the pragma.
Incidentally, note that only code in the module is optimized. Even with optimization on, evaluating g in the repl will always produce False, because the repl input is not subject to rewrite rules.

How can I add an extra switch in Leksah?

I would like to add an extra switch "-XDeriveDataTypeable" to the compiler.
Otherwise, I would like to able to compile Typeable.
Where can i do that in Leksah?
Generally
Here's a editor/ide-agnostic solution to your problem:
For language extensions, you can add this at the top of the source as a compiler pragma, which I prefer anyway:
{-# LANGUAGE DeriveDataTypeable #-}
instead of -XDeriveDataTypeable on the command line
You can pass other command line options to GHC, like this:
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
In Leksah
Leksah uses cabal for build configuration, so there's no special Leksah magic, that's all standard, but you can use the package editor as a GUI to edit the cabal file.
2/3 of the way down is the Extensions section where you can specify what language extensions you want.

Resources