packages feed

prettyprinter-interp (empty) → 0.1.0.0

raw patch · 5 files changed

+253/−0 lines, 5 filesdep +basedep +prettyprinterdep +prettyprinter-interp

Dependencies added: base, prettyprinter, prettyprinter-interp, string-interpolate, tasty, tasty-hunit, template-haskell, text

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for prettyprinter-interp++## 0.1.0.0 -- 2022-10-02++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) 2022, Peter Lebbing+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the+   distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ prettyprinter-interp.cabal view
@@ -0,0 +1,52 @@+cabal-version:      2.4+name:               prettyprinter-interp+version:            0.1.0.0+synopsis:           Efficient interpolation for Prettyprinter+description:+  This package provides efficient interpolation+  of @[string-interpolate](https://hackage.haskell.org/package/string-interpolate)@+  quasi quoters when used+  with @[prettyprinter](https://hackage.haskell.org/package/prettyprinter)@.+homepage:           https://github.com/DigitalBrains1/prettyprinter-interp+bug-reports:        https://github.com/DigitalBrains1/prettyprinter-interp/issues+license:            BSD-2-Clause+license-file:       LICENSE+author:             Peter Lebbing+maintainer:         peter@digitalbrains.com+copyright:          (C) 2022     , Peter Lebbing+category:           Data, Text+extra-source-files: CHANGELOG.md++source-repository head+  type:     git+  location: https://github.com/DigitalBrains1/prettyprinter-interp+source-repository this+  type:     git+  location: https://github.com/DigitalBrains1/prettyprinter-interp+  tag:      v0.1.0.0++library+  exposed-modules:    Prettyprinter.Interpolate++  build-depends:      base                      >=4.12      && < 4.18,+                      prettyprinter             >=1.2       && < 1.8,+                      string-interpolate        ^>=0.3.1,+                      template-haskell,+                      text                      >=1.2       && < 2.1,+  hs-source-dirs:     src+  default-language:   Haskell2010+  ghc-options:        -Wall -Wcompat++test-suite unittests+  default-language:   Haskell2010+  type:               exitcode-stdio-1.0+  hs-source-dirs:     test+  main-is:            unittests.hs+  build-depends:      base,+                      prettyprinter,+                      prettyprinter-interp,+                      string-interpolate,+                      tasty                     >= 1.2      && < 1.5,+                      tasty-hunit               ^>=0.10.0.2,+                      text,+  ghc-options:        -Wall -Wcompat
+ src/Prettyprinter/Interpolate.hs view
@@ -0,0 +1,141 @@+{-|+  Copyright   :  (C) 2022     , Peter Lebbing+  License     :  BSD2 (see the file LICENSE)+  Maintainer  :  Peter Lebbing <peter@digitalbrains.com>++  =Efficient interpolation for "Prettyprinter"++  This module provides efficient interpolation of+  [@string-interpolate@](https://hackage.haskell.org/package/string-interpolate)+  quasi quoters when used with+  [@prettyprinter@s](https://hackage.haskell.org/package/prettyprinter)+  'Prettyprinter.Doc'uments.++  The normal quasi quoters from @string-interpolate@ do work when used as a+  @Doc@. Newlines are even converted to @Prettyprinter.@'Prettyprinter.line'.+  However, this method is inefficient. The following code functions correctly:++  @+  {\-\# LANGUAGE OverloadedStrings \#-\}+  {\-\# LANGUAGE QuasiQuotes \#-\}++  module Main where++  import Data.String.Interpolate+  import Data.Text (Text)+  import Prettyprinter++  f :: 'Text'+  f = "world"++  g :: Doc ()+  g = ['i'|Hello #{f}!|]++  main :: IO ()+  main = print g+  @++  However, what happens under the hood is that @f@ is converted to 'String', the+  interpolated string is built manipulating @String@s, and then the output is+  converted to 'Data.Text.Text' in+  [@prettyprinter@](https://hackage.haskell.org/package/prettyprinter). The+  following code is much better:++  @+  g = 'pretty' ([i|Hello #{f}!|] :: Text)+  @++  Now, the interpolated string is constructed as @Text@, and this is passed+  cleanly into @Doc@ which also uses @Text@ as its underlying type for+  representation of text. At no point is @f@ converted to @String@, and the+  string construction benefits from the performance of @Text@. And again,+  newlines are converted to 'Prettyprinter.line'.++  This module defines wrapper quasi quoters that automatically perform the+  @pretty@ invocation, and can simply be used as:++  @+  g = ['di'|Hello #{f}!|]+  @+-}++{-# LANGUAGE CPP #-}+{-# LANGUAGE TemplateHaskell #-}++module Prettyprinter.Interpolate+  ( di+  , __di+  , diii+  , d__i'E+  , d__i'L+  , diii'E+  , diii'L+  ) where++#if MIN_VERSION_prettyprinter(1,7,0)+import Prettyprinter (Pretty(pretty))+#else+import Data.Text.Prettyprint.Doc (Pretty(pretty))+#endif++import Data.String.Interpolate+import Data.Text (Text)+import Language.Haskell.TH (Q)+import Language.Haskell.TH.Quote (QuasiQuoter(..))+import Language.Haskell.TH.Syntax (Name)++wrapper :: Name -> QuasiQuoter -> QuasiQuoter+wrapper nm wrapped = QuasiQuoter+  { quoteExp = \s -> [| pretty ($(quoteExp wrapped s) :: Text) |]+  , quotePat = const $ errQQType nm "pattern"+  , quoteType = const $ errQQType nm "type"+  , quoteDec = const $ errQQType nm "declaration"+  }++-- | Wrapper around the 'i' quasi quoter, producing a t'Prettyprinter.Doc'+--+-- Newlines in the text are converted to 'Prettyprinter.line'.+di :: QuasiQuoter+di = wrapper 'di i++-- | Wrapper around the '__i' quasi quoter, producing a t'Prettyprinter.Doc'+--+-- Newlines in the text are converted to 'Prettyprinter.line'.+__di :: QuasiQuoter+__di = wrapper '__di __i++-- | Wrapper around the 'iii' quasi quoter, producing a t'Prettyprinter.Doc'+--+-- Newlines in the text are converted to 'Prettyprinter.line'.+diii :: QuasiQuoter+diii = wrapper 'diii iii++-- | Wrapper around the '__i'E' quasi quoter, producing a t'Prettyprinter.Doc'+--+-- Newlines in the text are converted to 'Prettyprinter.line'.+d__i'E :: QuasiQuoter+d__i'E = wrapper 'd__i'E __i'E++-- | Wrapper around the '__i'L' quasi quoter, producing a t'Prettyprinter.Doc'+--+-- Newlines in the text are converted to 'Prettyprinter.line'.+d__i'L :: QuasiQuoter+d__i'L = wrapper 'd__i'L __i'L++-- | Wrapper around the 'iii'E' quasi quoter, producing a t'Prettyprinter.Doc'+--+-- Newlines in the text are converted to 'Prettyprinter.line'.+diii'E :: QuasiQuoter+diii'E = wrapper 'diii'E iii'E++-- | Wrapper around the 'iii'L' quasi quoter, producing a t'Prettyprinter.Doc'+--+-- Newlines in the text are converted to 'Prettyprinter.line'.+diii'L :: QuasiQuoter+diii'L = wrapper 'diii'L iii'L++errQQ :: Name -> String -> Q a+errQQ nm msg = fail $ show nm <> ": " <> msg++errQQType :: Name -> String -> Q a+errQQType nm ty = errQQ nm $ "This QuasiQuoter cannot be used as a " <> ty
+ test/unittests.hs view
@@ -0,0 +1,29 @@+{-|+  Copyright   :  (C) 2022     , Peter Lebbing+  License     :  BSD2 (see the file LICENSE)+  Maintainer  :  Peter Lebbing <peter@digitalbrains.com>+-}++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}++module Main where++import Data.Text (Text)+import Test.Tasty+import Test.Tasty.HUnit++import Prettyprinter.Interpolate++f :: Text+f = "world"++basicFunc :: Assertion+basicFunc = show [di|Hello #{f}!|] @?= "Hello world!"++tests :: TestTree+tests =+  testCase "Basic functionality" basicFunc++main :: IO ()+main = defaultMain tests