| Copyright | (C) 2016-2026 David M. Johnson |
|---|---|
| License | BSD3-style (see the file LICENSE) |
| Maintainer | David M. Johnson <code@dmj.io> |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | None |
| Language | Haskell2010 |
Miso.FFI.QQ
Description
Overview
Miso.FFI.QQ provides the quasi-quoter, which lets you embed
JavaScript snippets directly in Haskell source. In-scope Haskell
variables are spliced into the JS body with js${varName} interpolation
syntax, and their types are checked at compile time via
ToJSVal.
Enable the extension and import the quoter:
{-# LANGUAGE QuasiQuotes #-}
import Miso.FFI.QQ (js)
Quick start
-- Compute a factorial entirely in JavaScript fac :: Int -> IO Int fac n = [js| let x = 1; for (let i = 1; i <= ${n}; i++) { x *= i; } return x; |] -- Call a third-party JS library with a DOM reference and a string highlight ::JSVal->MisoString-> IO () highlight domRef lang = [js| hljs.highlightElement(${domRef}, { language: ${lang} }); |]
How it works
At compile time the quasi-quoter:
- Lexes the JS body to find all
${varName}interpolations. - Looks up each
varNamein the Haskell scope (compile error if not found). - Builds a
Objectmapping short generated keys to the marshalled values (viainline/createWith). - Rewrites the JS body, replacing each
${varName}with its generated key, and wraps the whole thing in a JS function so the keys are visible as named parameters.
The result is semantically equivalent to:
do o <-createWith[("a0", toJSVal n)]inline"… body with a0 instead of n …" o
Differences from eval
Unlike eval, the generated code runs in a fresh function scope —
it cannot read or write surrounding local variables other than those
explicitly interpolated. This makes it both safer and faster (JS engines
can optimise closed-over functions that don't reference eval).
See also
inline— the runtime primitive this expands to- Miso.DSL —
ToJSVal,createWith - Miso.FFI — higher-level browser API wrappers
Synopsis
- js :: QuasiQuoter
Documentation
js :: QuasiQuoter Source #
QuasiQuoter for specifying inline JavaScript.