Home > database >  Specify default string type from the Quasi quoter
Specify default string type from the Quasi quoter

Time:08-02

I want to use PyF library. It has a formatter fmt:

-- | Generic formatter, can format an expression to any @t@ as long as
--   @t@ is an instance of 'IsString'.
fmt :: QuasiQuoter
fmt = mkFormatter "fmt" fmtConfig

from https://hackage.haskell.org/package/PyF-0.10.2.0/docs/src/PyF.html#fmt.

But I am trying to use it with a logging library which gets any string-like objects. And fmt returns IsString. So, to mix them together I need to specify the type - ::String for example.

$(debug) "mylogger" ([fmt|Make a socket: port={port} ...|]::String)

But I don't want to do it. Is it possible to write own fmt' version that will return always lets say String? Something like

fmt' = .... fmt ....

How will it look?

CodePudding user response:

Some other relevant definitions from PyF:

-- | If 'OverloadedStrings' is enabled, from the input expression with
-- 'fromString'.
wrapFromString :: ExpQ -> Q Exp
wrapFromString e = do
  exts <- extsEnabled
  if OverloadedStrings `elem` exts
    then [|fromString $(e)|]
    else e

-- | Configuration for 'str' it just wrap the multiline string with 'fromString'.
strConfig :: Config
strConfig =
  Config
    { delimiters = Nothing,
      postProcess = wrapFromString
    }

-- | The config for 'fmt'.
fmtConfig :: Config
fmtConfig = addFormatting ('{', '}') strConfig

Here it is wrapFromString which explicitly uses fromString to convert the expression of type String to IsString s => s. It only does so if the OverloadedStrings extension is enabled, so you could just disable that. If you want to use OverloadedStrings but also have the format string always have type String, you can define

fmt' = mkFormatter "fmt" (addFormatting ('{', '}') myConfig) where
  myConfig = Config
    { delimiters = Nothing,
      postProcess = id // note: simply removed `wrapFromString' here
    }
  • Related