Giter Site home page Giter Site logo

cdepillabout / heterocephalus-example Goto Github PK

View Code? Open in Web Editor NEW
5.0 5.0 0.0 18 KB

simple explanation on how to use -ddump-splices with stack

Home Page: https://functor.tokyo/blog/2017-01-16-looking-at-generated-template-haskell

License: BSD 3-Clause "New" or "Revised" License

Haskell 100.00%
template-haskell haskell ddump-splices tutorial example

heterocephalus-example's Introduction

Using -ddump-splices

Build Status

When debugging Haskell code, it can be useful to look at the code generated from Template Haskell and Quasiquote expressions. This repository is a tutorial explaining an easy way to view the generated Haskell code.

The Intro

This repository contains a single Haskell file, Example.hs. It is a small example of using heterocephalus, a type-safe template engine.

The Haskell code defining the template looks like this:

template :: Html
template =
  let a = "hello"
      b = 3 :: Int
      cs = ["foo", "bar", "baz"]
  in [compileText|
variable interpolation:
  #{a}

if control statement:
%{ if (b == 3) }
  b is 3
%{ else }
  b is some other number
%{ endif }

forall control statement:
%{ forall c <- cs }
  #{c}
%{ endforall }
   |]

Everything within the compileText quasiquote is expanded at compile-time into Haskell code. This tutorial explains how to see exactly what code is generated.

The Setup

First, clone this repository and cd into it.

$ git clone https://github.com/cdepillabout/heterocephalus-example.git
$ cd heterocephalus-example/

This tutorial assumes you are using stack. You need to install stack if you haven't already done so.

If GHC is not installed, it can be installed with stack setup.

$ stack setup

Now that GHC is installed, the example program can be built with stack build.

$ stack build

The example program is built and placed somewhere under the .stack-work/ directory. stack exec can be used to execute it:

$ stack exec -- heterocephalus-example

variable interpolation:
  hello

if control statement:
  b is 3

forall control statement:
  foo
  bar
  baz

-ddump-splices

The example program needs to be compiled with the GHC flag -ddump-splices in order to get GHC/Stack to dump the generated Haskell code to a file.

If the example program has already been built (as above), then stack clean needs to be run to make sure the executable gets rebuilt. After that, stack build can be run again, but this time with the -ddump-splices flag.

$ stack clean
$ stack build --ghc-options="-ddump-splices"

NOTE: Not running stack clean first can cause stack build to appear to succeed, but no splice file to be generated. Make sure stack clean is run before stack build whenever -ddump-splices is being used.

GHC/Stack will generate a splice file somewhere under .stack-work/. The location of the splice file will change depending on the architecture and Cabal version. find can be used to figure out where the splice file is.

$ find .stack-work/ -name '*.dump-splices'
.stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/heterocephalus-example/heterocephalus-example-tmp/app/Example.dump-splices

This .dump-splices file will show what Haskell code is generated from each Template Haskell and quasiquote expression.

For example, a quasiquote like this:

[compileText|foo #{a}|]

would produce Haskell code that looks like this (slightly simplified):

do
  preEscapedText "foo "
  preEscapedToMarkup a

Generated Code for the Example Template

Lets go back to the example program. Once again, the template is defined like this:

template :: Html
template =
  let a = "hello"
      b = 3 :: Int
      cs = ["foo", "bar", "baz"]
  in [compileText|
variable interpolation:
  #{a}

if control statement:
%{ if (b == 3) }
  b is 3
%{ else }
  b is some other number
%{ endif }

forall control statement:
%{ forall c <- cs }
  #{c}
%{ endforall }
   |]

If this is compiled with the -ddump-splices flag, the output Example.dump-splices file will look like this (after being cleaned up a little to make it more readable):

app/Example.hs:(15,19)-(30,5): Splicing expression
    template-haskell-2.11.0.0:Language.Haskell.TH.Quote.quoteExp
      compileText
      "variable interpolation:
         #{a}

       if control statement:
       %{ if (b == 3) }
         b is 3
       %{ else }
         b is some other number
       %{ endif }

       forall control statement:
       %{ forall c <- cs }
         #{c}
       %{ endforall }
          "
  ======>
    do
      preEscapedText "variable interpolation:\n"
      preEscapedToMarkup a
      preEscapedText "\n\nif control statement:\n"
      condH
        [(b == 3, preEscapedText "  b is 3")]
        (Just (preEscapedText "  b is some other number"))
      preEscapedText "\n\nforall control statement:\n"
      forM_ cs $ \c -> do
        preEscapedText "  "
        preEscapedToMarkup c
        preEscapedText "\n"

Above the =======> line, you can see the quasiquote as it exists in the Haskell file. Below the line, you can see the Haskell code that GHC has generated.

Conclusion

Sometimes it is difficult to read the splice files, but it there is often no other way to easily debug Template Haskell and quasiquotes.

heterocephalus-example's People

Contributors

cdepillabout avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.