3

How can I interpolate like this:

{-# LANGUAGE QuasiQuotes #-}
import Text.RawString.QQ

myText :: Text -> Text
myText myVariable = [r|line one
line two
line tree
${ myVariable }
line five|]

myText' :: Text
myText' = myText "line four"

${ myVariable } prints as a literal, not an interpolation, can I do something similar that to interpolate in this case?

FtheBuilder
  • 1,410
  • 12
  • 19
  • 1
    Well, what did you expect? It's precisely the point of the `r` quasi-quoter to replicate text as-is, without any escaping etc.. You're going to need a different quasi-quoter to get this behaviour. But that's off topic for an SO question. Why haven't you [just searched hackage](http://hackage.haskell.org/packages/search?terms=interpolation) though? — FWIW, I dislike both the term interpolation in this context, and the technique itself. It's generally better to build up such strings from chunks, this can be done nicely with [fmt](http://hackage.haskell.org/package/fmt-0.6/docs/Fmt.html). – leftaroundabout Jun 04 '18 at 20:36
  • 1
    @leftaroundabout I think interpolation could be useful. Sometimes you can big predefined chunk of text where you need to configure only small parts. See example in [`summoner`](https://github.com/kowainik/summoner/blob/21c4bbf2888b232ee8937e0d880cb438d9514d81/src/Summoner/Template.hs#L363). `fmt`package is good when you need to format small messages in custom way using a bunch of predefined operators (especially for dates). Something like that: https://github.com/serokell/importify/blob/3c26c156306b6a95ea1e02344c785354cac59d98/src/Importify/Main/Cache.hs#L92-L93 – Shersh Jun 05 '18 at 06:47

2 Answers2

5

Quasi quoter r doesn't implement interpolation. It's only for raw strings. You need another quasi quoter.

Complete code:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}

import Data.Text (Text)
import Text.RawString.QQ (r)
import NeatInterpolation (text)

rQuote :: Text -> Text
rQuote myVariable = [r|line one
line two
line tree
${ myVariable }
line five|]

neatQuote :: Text -> Text
neatQuote myVariable = [text|line one
line two
line tree
$myVariable
line five|]

rText, neatText :: Text
rText    = rQuote    "line four"
neatText = neatQuote "line four"

In ghci:

*Main> import Data.Text.IO as TIO
*Main TIO> TIO.putStrLn rText
line one
line two
line tree
${ myVariable }
line five
*Main TIO> TIO.putStrLn neatText
line one
line two
line tree
line four
line five
Shersh
  • 9,019
  • 3
  • 33
  • 61
2

The only way I achieved my objective was just by concatenating:

{-# LANGUAGE QuasiQuotes #-}
import Text.RawString.QQ

myText :: Text -> Text
myText myVariable = [r|line one
line two
line tree
|] <> myVariable <> [r|
line five|]

myText' :: Text
myText' = myText "line four"
FtheBuilder
  • 1,410
  • 12
  • 19