PyF 0.10.2.0 → 0.11.0.0
raw patch · 96 files changed
+799/−716 lines, 96 filesdep ~basedep ~bytestringdep ~ghcPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, bytestring, ghc, ghc-boot, mtl, parsec, template-haskell, text, time
API changes (from Hackage documentation)
- PyF.Internal.Meta: translateTHtoGHCExt :: Extension -> Extension
- PyF.Internal.PythonSyntax: instance GHC.Show.Show PyF.Internal.PythonSyntax.FormatMode
- PyF.Internal.PythonSyntax: instance GHC.Show.Show PyF.Internal.PythonSyntax.Item
- PyF.Internal.PythonSyntax: instance GHC.Show.Show PyF.Internal.PythonSyntax.Padding
- PyF.Internal.PythonSyntax: instance GHC.Show.Show PyF.Internal.PythonSyntax.Precision
- PyF.Internal.PythonSyntax: instance GHC.Show.Show PyF.Internal.PythonSyntax.TypeFormat
- PyF.Internal.PythonSyntax: instance GHC.Show.Show t => GHC.Show.Show (PyF.Internal.PythonSyntax.ExprOrValue t)
+ PyF.Formatters: instance Data.Data.Data PyF.Formatters.SignMode
+ PyF.Internal.Meta: toName :: RdrName -> Name
+ PyF.Internal.PythonSyntax: instance Data.Data.Data PyF.Internal.PythonSyntax.AlternateForm
+ PyF.Internal.PythonSyntax: instance Data.Data.Data PyF.Internal.PythonSyntax.Precision
+ PyF.Internal.PythonSyntax: instance Data.Data.Data PyF.Internal.PythonSyntax.TypeFormat
+ PyF.Internal.PythonSyntax: instance Data.Data.Data t => Data.Data.Data (PyF.Internal.PythonSyntax.ExprOrValue t)
- PyF.Internal.Parser: parseExpression :: String -> DynFlags -> Either (Int, Int, String) (HsExpr GhcPs)
+ PyF.Internal.Parser: parseExpression :: RealSrcLoc -> String -> DynFlags -> Either (Int, Int, String) (HsExpr GhcPs)
- PyF.Internal.ParserEx: parseExpression :: String -> DynFlags -> ParseResult (Located (HsExpr GhcPs))
+ PyF.Internal.ParserEx: parseExpression :: RealSrcLoc -> String -> DynFlags -> ParseResult (Located (HsExpr GhcPs))
- PyF.Internal.PythonSyntax: HaskellExpr :: Exp -> ExprOrValue t
+ PyF.Internal.PythonSyntax: HaskellExpr :: (HsExpr GhcPs, Exp) -> ExprOrValue t
- PyF.Internal.PythonSyntax: Replacement :: Exp -> Maybe FormatMode -> Item
+ PyF.Internal.PythonSyntax: Replacement :: (HsExpr GhcPs, Exp) -> Maybe FormatMode -> Item
Files
- ChangeLog.md +9/−0
- PyF.cabal +11/−11
- Readme.md +15/−6
- src/PyF/Formatters.hs +8/−5
- src/PyF/Internal/Meta.hs +29/−148
- src/PyF/Internal/Parser.hs +25/−5
- src/PyF/Internal/ParserEx.hs +19/−12
- src/PyF/Internal/PythonSyntax.hs +41/−23
- src/PyF/Internal/QQ.hs +186/−60
- test/Spec.hs +46/−2
- test/SpecFail.hs +37/−6
- test/golden/Hello {length name}.16675806454852491955.golden +7/−0
- test/golden/Hello {name}.16618004304593959603.golden +7/−0
- test/golden/Hello {piCL.{precision}}.9628757040831863475.golden +7/−0
- test/golden/Hello {piCL.{truncate number + precision}}.18094049741103110835.golden +7/−0
- test/golden/Hello {piCL{width}}.15463239215289408179.golden +7/−0
- test/golden/fooBACKSLASHPbar.golden +0/−12
- test/golden/fooBSPbar.17645057532673886893.golden +7/−0
- test/golden/fooNEWLINEbliBACKSLASHPbar.golden +0/−13
- test/golden/fooNLbliBSPbar.16759496276764189145.golden +8/−0
- test/golden/hello { world.10778336899993839283.golden +9/−0
- test/golden/hello { world.golden +0/−14
- test/golden/hello } world.5295037443422799539.golden +9/−0
- test/golden/hello } world.golden +0/−14
- test/golden/helloNEWLINE {NEWLINElet a = 5NEWLINE b = 10NEWLINEin 1 + - SLASH lalalal}.golden +0/−16
- test/golden/helloNEWLINENEWLINENEWLINE{piCOLONl}.golden +0/−17
- test/golden/helloNL {NLlet a = 5NL b = 10NLin 1 + - SL lalalal}.3018767237106994099.golden +11/−0
- test/golden/helloNLNLNL{piCLl}.13123157148160021427.golden +12/−0
- test/golden/{1 + - SL lalalal}.14923086665437293731.golden +7/−0
- test/golden/{1 + - SLASH lalalal}.golden +0/−12
- test/golden/{TrueCLd}.12627313193367841398.golden +9/−0
- test/golden/{TrueCLf}.18281408089045870326.golden +9/−0
- test/golden/{TrueCOLONd}.golden +0/−9
- test/golden/{TrueCOLONf}.golden +0/−9
- test/golden/{True}.16254223077612353942.golden +9/−0
- test/golden/{True}.golden +0/−9
- test/golden/{helloCL s}.13047921915648718386.golden +7/−0
- test/golden/{helloCL%}.1257653362598537778.golden +9/−0
- test/golden/{helloCL+s}.1657517030647448626.golden +7/−0
- test/golden/{helloCL,s}.14139635988852178482.golden +7/−0
- test/golden/{helloCL-s}.12627805606214404146.golden +7/−0
- test/golden/{helloCL=100s}.14374776122070431282.golden +7/−0
- test/golden/{helloCL=100}.9444838110946424370.golden +9/−0
- test/golden/{helloCLE}.15676531368138664498.golden +9/−0
- test/golden/{helloCLG}.17442699390234010162.golden +9/−0
- test/golden/{helloCLX}.8447528333473699378.golden +9/−0
- test/golden/{helloCL_s}.1094067961907256370.golden +7/−0
- test/golden/{helloCLb}.14869862508711808562.golden +9/−0
- test/golden/{helloCLd}.1892681375540151858.golden +9/−0
- test/golden/{helloCLe}.13933826712837941810.golden +9/−0
- test/golden/{helloCLf}.14332487603622862386.golden +9/−0
- test/golden/{helloCLg}.9607247906229690930.golden +9/−0
- test/golden/{helloCLo}.9389880575827657266.golden +9/−0
- test/golden/{helloCLx}.14710080644372944434.golden +9/−0
- test/golden/{helloCOLON s}.golden +0/−12
- test/golden/{helloCOLON%}.golden +0/−9
- test/golden/{helloCOLON+s}.golden +0/−12
- test/golden/{helloCOLON,s}.golden +0/−12
- test/golden/{helloCOLON-s}.golden +0/−12
- test/golden/{helloCOLON=100s}.golden +0/−12
- test/golden/{helloCOLON=100}.golden +0/−9
- test/golden/{helloCOLONE}.golden +0/−9
- test/golden/{helloCOLONG}.golden +0/−9
- test/golden/{helloCOLONX}.golden +0/−9
- test/golden/{helloCOLON_s}.golden +0/−12
- test/golden/{helloCOLONb}.golden +0/−9
- test/golden/{helloCOLONd}.golden +0/−9
- test/golden/{helloCOLONe}.golden +0/−9
- test/golden/{helloCOLONf}.golden +0/−9
- test/golden/{helloCOLONg}.golden +0/−9
- test/golden/{helloCOLONo}.golden +0/−9
- test/golden/{helloCOLONx}.golden +0/−9
- test/golden/{numberCLX}.4609648040604121432.golden +9/−0
- test/golden/{numberCLb}.8801685868342243288.golden +9/−0
- test/golden/{numberCLd}.13336740346716692056.golden +9/−0
- test/golden/{numberCLo}.12467189151987896600.golden +9/−0
- test/golden/{numberCLx}.14457861675063419224.golden +9/−0
- test/golden/{numberCOLONX}.golden +0/−9
- test/golden/{numberCOLONb}.golden +0/−9
- test/golden/{numberCOLONd}.golden +0/−9
- test/golden/{numberCOLONo}.golden +0/−9
- test/golden/{numberCOLONx}.golden +0/−9
- test/golden/{piCL.{SL}}.6840925804160914882.golden +7/−0
- test/golden/{piCL.{}}.9894464503607709506.golden +9/−0
- test/golden/{piCOLON.{SLASH}}.golden +0/−12
- test/golden/{piCOLON.{}}.golden +0/−14
- test/golden/{truncate numberCL.3b}.11608798523190422838.golden +7/−0
- test/golden/{truncate numberCL.3d}.9142976352287206710.golden +7/−0
- test/golden/{truncate numberCL.3o}.1443712191031422262.golden +7/−0
- test/golden/{truncate numberCL.3x}.12613302271643495734.golden +7/−0
- test/golden/{truncate numberCOLON.3b}.golden +0/−12
- test/golden/{truncate numberCOLON.3d}.golden +0/−12
- test/golden/{truncate numberCOLON.3o}.golden +0/−12
- test/golden/{truncate numberCOLON.3x}.golden +0/−12
- test/golden/{}.14986928820806517861.golden +9/−0
- test/golden/{}.golden +0/−14
ChangeLog.md view
@@ -1,5 +1,14 @@ # Revision history for PyF +## 0.11.0.0 -- 2022-08-10++- Support for GHC 9.4. (Written with a pre-release of GHC 9.4, hopefully it won't change too much before the release).+- Error reporting now uses the native GHC API. In summary, it means that+ haskell-language-server will point to the correct location of the error, not+ the beginning of the quasi quotes.+- PyF will now correctly locate the error for variable not found in expression, even if the expression is complicated. The support for complex expression is limited, and PyF may return a false positive if you try to format a complex lambda / case expression. Please open a ticket if you need that.+- Add support for literal `[]` and `()` in haskell expression.+- Add support for overloaded labels, thank you Shimuuar. - Support for `::` in haskell expression. Such as `[fmt| 10 :: Int:d}|]`, as a suggestion from julm (close #87). - `Integral` padding width and precision also for formatter without type specifier. - Extra care was used to catch all `type-defaults` warning message. PyF should
PyF.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: PyF-version: 0.10.2.0+version: 0.11.0.0 synopsis: Quasiquotations for a python like interpolated string formatter description: Quasiquotations for a python like interpolated string formatter. license: BSD-3-Clause@@ -27,15 +27,15 @@ PyF.Internal.ParserEx PyF.Internal.Parser - build-depends: base >= 4.9 && < 5.0- , bytestring- , template-haskell- , text- , time- , parsec- , mtl- , ghc- , ghc-boot+ build-depends: base >= 4.12 && < 4.17+ , bytestring >= 0.10.8 && < 0.12+ , template-haskell >= 2.14.0 && < 2.19+ , text >= 1.2.3 && <= 2.0+ , time >= 1.8.0 && < 1.13+ , parsec >= 3.1.13 && < 3.2+ , mtl >= 2.2.2 && < 2.3+ , ghc >= 8.6.1 && < 9.4+ , ghc-boot >= 8.6.1 && < 9.4 hs-source-dirs: src ghc-options: -Wall -Wunused-packages -Wincomplete-uni-patterns default-language: Haskell2010@@ -65,7 +65,7 @@ type: exitcode-stdio-1.0 hs-source-dirs: test main-is: SpecFail.hs- build-depends: base, hspec, text, process, hspec, temporary, filepath, deepseq, HUnit+ build-depends: base, hspec, text, process, hspec, temporary, filepath, deepseq, HUnit, PyF ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N -Wunused-packages default-language: Haskell2010
Readme.md view
@@ -203,21 +203,30 @@ - Any parsing error on the mini language results in a clear indication of the error, for example: ```haskell->>> [fmt|{age:.3d}|]+foo = [fmt|{age:.3d}|]+``` -<interactive>:77:4: error:- • <interactive>:1:8:+```+File.hs:77:19: error: | 1 | {age:.3d} | ^ Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field. ``` +Note: error reporting uses the native GHC error infrastructure, so they will correctly appear in your editor (using [HLS](https://github.com/haskell/haskell-language-server)), for example:++ + - Error in variable name are also readable: ```haskell->>> [fmt|{toto}|]-<interactive>:78:4: error: Variable not in scope: toto+test/SpecUtils.hs:81:33: error:+ • Variable not found: chien+ • In the quasi-quotation: [fmt|A missing variable: {chien}|]+ |+81 | fiz = [fmt|A missing variable: {chien}|]+ | ^^^^^ ``` - However, if the interpolated name is not of a compatible type (or@@ -242,7 +251,7 @@ ... ``` -- Finally, if you make any type error inside the expression field, you are on your own:+- Finally, if you make any type error inside the expression field, you are on your own, you'll get an awful error in the middle of the generated template Haskell splice. ```haskell >>> [fmt|{3 + pi + "hello":10}|]
src/PyF/Formatters.hs view
@@ -5,10 +5,11 @@ {-# LANGUAGE KindSignatures #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TypeApplications #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE DeriveDataTypeable #-} -- | --@@ -55,6 +56,7 @@ import Data.List (intercalate) import Language.Haskell.TH.Syntax import qualified Numeric+import Data.Data (Data) -- ADT for API @@ -66,7 +68,7 @@ Minus | -- | Display '-' sign and a space for positive numbers Space- deriving (Show)+ deriving (Show, Data) data AlignForString = AlignAll | AlignNumber deriving (Show)@@ -79,9 +81,10 @@ AlignRight :: AlignMode 'AlignAll -- | Padding will be added between the sign and the number AlignInside :: AlignMode 'AlignNumber- -- | Padding will be added around the valueber+ -- | Padding will be added around the value AlignCenter :: AlignMode 'AlignAll + deriving instance Show (AlignMode k) -- The generic version@@ -277,7 +280,7 @@ -- | Format an integral number formatIntegral ::- Integral paddingWidth => + Integral paddingWidth => Integral i => Format t t' 'Integral -> SignMode ->
src/PyF/Internal/Meta.hs view
@@ -4,7 +4,7 @@ {-# LANGUAGE TemplateHaskellQuotes #-} {-# LANGUAGE ViewPatterns #-} -module PyF.Internal.Meta (toExp, baseDynFlags, translateTHtoGHCExt) where+module PyF.Internal.Meta (toExp, baseDynFlags, toName) where #if MIN_VERSION_ghc(9,2,0) import GHC.Hs.Type (HsWildCardBndrs (..), HsType (..), HsSigType(HsSig), sig_body)@@ -42,9 +42,9 @@ import GHC.Utils.Outputable (ppr) import GHC.Types.Basic (Boxity(..)) import GHC.Types.SourceText (il_value, rationalFromFractionalLit)-import GHC.Driver.Ppr (showSDocDebug)+import GHC.Driver.Ppr (showSDoc) #else-import GHC.Utils.Outputable (ppr, showSDocDebug)+import GHC.Utils.Outputable (ppr, showSDoc) import GHC.Types.Basic (il_value, fl_value, Boxity(..)) #endif import GHC.Driver.Session (DynFlags, xopt_set, defaultDynFlags)@@ -54,7 +54,7 @@ import Name import RdrName import FastString-import Outputable (ppr, showSDocDebug)+import Outputable (ppr, showSDoc) import BasicTypes (il_value, fl_value, Boxity(..)) import DynFlags (DynFlags, xopt_set, defaultDynFlags) import qualified Module@@ -98,22 +98,27 @@ in if isRdrTyVar n' then TH.VarT (toName n') else TH.ConT (toName n')-toType t = todo "toType" (showSDocDebug (baseDynFlags []) . ppr $ t)+toType t = todo "toType" (showSDoc (baseDynFlags []) . ppr $ t) toName :: RdrName -> TH.Name toName n = case n of (Unqual o) -> TH.mkName (occNameString o) (Qual m o) -> TH.mkName (Module.moduleNameString m <> "." <> occNameString o)- (Orig m o) -> error "orig"- (Exact n1) -> error "exact"+ (Orig _m _o) -> error "PyFMeta: not supported toName (Orig _)"+ (Exact nm) -> case getOccString nm of+ "[]" -> '[]+ "()" -> '()+ _ -> error "toName: exact name encountered" toFieldExp :: a toFieldExp = undefined toPat :: DynFlags -> Pat.Pat GhcPs -> TH.Pat toPat _dynFlags (Pat.VarPat _ (unLoc -> name)) = TH.VarP (toName name)-toPat dynFlags p = todo "toPat" (showSDocDebug dynFlags . ppr $ p)+toPat dynFlags p = todo "Advanced pattern match are not supported in PyF. See https://github.com/guibou/PyF/issues/107 if that's a problem for you." (showSDoc dynFlags . ppr $ p) +{- ORMOLU_DISABLE -}+ toExp :: DynFlags -> Expr.HsExpr GhcPs -> TH.Exp toExp _ (Expr.HsVar _ n) = let n' = unLoc n@@ -137,6 +142,7 @@ toExp d (Expr.ExprWithTySig _ e HsWC{hswc_body=HsIB{hsib_body}}) = TH.SigE (toExp d . unLoc $ e) (toType . unLoc $ hsib_body) #else toExp d (Expr.HsAppType HsWC {hswc_body} e) = TH.AppTypeE (toExp d . unLoc $ e) (toType . unLoc $ hswc_body)+toExp d (Expr.ExprWithTySig HsWC{hswc_body=HsIB{hsib_body}} e) = TH.SigE (toExp d . unLoc $ e) (toType . unLoc $ hsib_body) #endif toExp d (Expr.OpApp _ e1 o e2) = TH.UInfixE (toExp d . unLoc $ e1) (toExp d . unLoc $ o) (toExp d . unLoc $ e2) toExp d (Expr.NegApp _ e _) = TH.AppE (TH.VarE 'negate) (toExp d . unLoc $ e)@@ -170,12 +176,19 @@ Just args -> fmap (toExp d) args #endif +{- ORMOLU_ENABLE -}+ -- toExp (Expr.List _ xs) = TH.ListE (fmap toExp xs)+#if MIN_VERSION_ghc(9,3,0)+toExp d (Expr.HsPar _ _ e _) = TH.ParensE (toExp d . unLoc $ e)+#else toExp d (Expr.HsPar _ e) = TH.ParensE (toExp d . unLoc $ e)+#endif toExp d (Expr.SectionL _ (unLoc -> a) (unLoc -> b)) = TH.InfixE (Just . toExp d $ a) (toExp d b) Nothing toExp d (Expr.SectionR _ (unLoc -> a) (unLoc -> b)) = TH.InfixE Nothing (toExp d a) (Just . toExp d $ b) toExp _ (Expr.RecordCon _ name HsRecFields {rec_flds}) = TH.RecConE (toName . unLoc $ name) (fmap toFieldExp rec_flds)+ -- toExp (Expr.RecUpdate _ e xs) = TH.RecUpdE (toExp e) (fmap toFieldExp xs) -- toExp (Expr.ListComp _ e ss) = TH.CompE $ map convert ss ++ [TH.NoBindS (toExp e)] -- where@@ -192,7 +205,14 @@ (FromThen a b) -> TH.FromThenR (toExp d $ unLoc a) (toExp d $ unLoc b) (FromTo a b) -> TH.FromToR (toExp d $ unLoc a) (toExp d $ unLoc b) (FromThenTo a b c) -> TH.FromThenToR (toExp d $ unLoc a) (toExp d $ unLoc b) (toExp d $ unLoc c)-toExp dynFlags e = todo "toExp" (showSDocDebug dynFlags . ppr $ e)+#if MIN_VERSION_ghc(9, 2, 0)+toExp _ (HsOverLabel _ lbl) = TH.LabelE (unpackFS lbl)+#else+-- It's not quite clear what to do in case when overloaded syntax is+-- enabled thus match on Nothing+toExp _ (HsOverLabel _ Nothing lbl) = TH.LabelE (unpackFS lbl)+#endif+toExp dynFlags e = todo "toExp" (showSDoc dynFlags . ppr $ e) todo :: (HasCallStack, Show e) => String -> e -> a todo fun thing = error . concat $ [moduleName, ".", fun, ": not implemented: ", show thing]@@ -207,142 +227,3 @@ baseDynFlags exts = let enable = GhcTH.TemplateHaskellQuotes : exts in foldl xopt_set (defaultDynFlags fakeSettings fakeLlvmConfig) enable--translateTHtoGHCExt :: TH.Extension -> GhcTH.Extension-translateTHtoGHCExt TH.Cpp = GhcTH.Cpp-translateTHtoGHCExt TH.OverlappingInstances = GhcTH.OverlappingInstances-translateTHtoGHCExt TH.UndecidableInstances = GhcTH.UndecidableInstances-translateTHtoGHCExt TH.IncoherentInstances = GhcTH.IncoherentInstances-translateTHtoGHCExt TH.UndecidableSuperClasses = GhcTH.UndecidableSuperClasses-translateTHtoGHCExt TH.MonomorphismRestriction = GhcTH.MonomorphismRestriction-#if ! MIN_VERSION_ghc(9,2,0)-translateTHtoGHCExt TH.MonoPatBinds = GhcTH.MonoPatBinds-#endif-translateTHtoGHCExt TH.MonoLocalBinds = GhcTH.MonoLocalBinds-translateTHtoGHCExt TH.RelaxedPolyRec = GhcTH.RelaxedPolyRec-translateTHtoGHCExt TH.ExtendedDefaultRules = GhcTH.ExtendedDefaultRules-translateTHtoGHCExt TH.ForeignFunctionInterface = GhcTH.ForeignFunctionInterface-translateTHtoGHCExt TH.UnliftedFFITypes = GhcTH.UnliftedFFITypes-translateTHtoGHCExt TH.InterruptibleFFI = GhcTH.InterruptibleFFI-translateTHtoGHCExt TH.CApiFFI = GhcTH.CApiFFI-translateTHtoGHCExt TH.GHCForeignImportPrim = GhcTH.GHCForeignImportPrim-translateTHtoGHCExt TH.JavaScriptFFI = GhcTH.JavaScriptFFI-translateTHtoGHCExt TH.ParallelArrays = GhcTH.ParallelArrays-translateTHtoGHCExt TH.Arrows = GhcTH.Arrows-translateTHtoGHCExt TH.TemplateHaskell = GhcTH.TemplateHaskell-translateTHtoGHCExt TH.TemplateHaskellQuotes = GhcTH.TemplateHaskellQuotes-translateTHtoGHCExt TH.QuasiQuotes = GhcTH.QuasiQuotes-translateTHtoGHCExt TH.ImplicitParams = GhcTH.ImplicitParams-translateTHtoGHCExt TH.ImplicitPrelude = GhcTH.ImplicitPrelude-translateTHtoGHCExt TH.ScopedTypeVariables = GhcTH.ScopedTypeVariables-translateTHtoGHCExt TH.AllowAmbiguousTypes = GhcTH.AllowAmbiguousTypes-translateTHtoGHCExt TH.UnboxedTuples = GhcTH.UnboxedTuples-translateTHtoGHCExt TH.UnboxedSums = GhcTH.UnboxedSums-translateTHtoGHCExt TH.BangPatterns = GhcTH.BangPatterns-translateTHtoGHCExt TH.TypeFamilies = GhcTH.TypeFamilies-translateTHtoGHCExt TH.TypeFamilyDependencies = GhcTH.TypeFamilyDependencies-translateTHtoGHCExt TH.TypeInType = GhcTH.TypeInType-translateTHtoGHCExt TH.OverloadedStrings = GhcTH.OverloadedStrings-translateTHtoGHCExt TH.OverloadedLists = GhcTH.OverloadedLists-translateTHtoGHCExt TH.NumDecimals = GhcTH.NumDecimals-translateTHtoGHCExt TH.DisambiguateRecordFields = GhcTH.DisambiguateRecordFields-translateTHtoGHCExt TH.RecordWildCards = GhcTH.RecordWildCards-translateTHtoGHCExt TH.RecordPuns = GhcTH.RecordPuns-translateTHtoGHCExt TH.ViewPatterns = GhcTH.ViewPatterns-translateTHtoGHCExt TH.GADTs = GhcTH.GADTs-translateTHtoGHCExt TH.GADTSyntax = GhcTH.GADTSyntax-translateTHtoGHCExt TH.NPlusKPatterns = GhcTH.NPlusKPatterns-translateTHtoGHCExt TH.DoAndIfThenElse = GhcTH.DoAndIfThenElse-translateTHtoGHCExt TH.BlockArguments = GhcTH.BlockArguments-translateTHtoGHCExt TH.RebindableSyntax = GhcTH.RebindableSyntax-translateTHtoGHCExt TH.ConstraintKinds = GhcTH.ConstraintKinds-translateTHtoGHCExt TH.PolyKinds = GhcTH.PolyKinds-translateTHtoGHCExt TH.DataKinds = GhcTH.DataKinds-translateTHtoGHCExt TH.InstanceSigs = GhcTH.InstanceSigs-translateTHtoGHCExt TH.ApplicativeDo = GhcTH.ApplicativeDo-translateTHtoGHCExt TH.StandaloneDeriving = GhcTH.StandaloneDeriving-translateTHtoGHCExt TH.DeriveDataTypeable = GhcTH.DeriveDataTypeable-translateTHtoGHCExt TH.AutoDeriveTypeable = GhcTH.AutoDeriveTypeable-translateTHtoGHCExt TH.DeriveFunctor = GhcTH.DeriveFunctor-translateTHtoGHCExt TH.DeriveTraversable = GhcTH.DeriveTraversable-translateTHtoGHCExt TH.DeriveFoldable = GhcTH.DeriveFoldable-translateTHtoGHCExt TH.DeriveGeneric = GhcTH.DeriveGeneric-translateTHtoGHCExt TH.DefaultSignatures = GhcTH.DefaultSignatures-translateTHtoGHCExt TH.DeriveAnyClass = GhcTH.DeriveAnyClass-translateTHtoGHCExt TH.DeriveLift = GhcTH.DeriveLift-translateTHtoGHCExt TH.DerivingStrategies = GhcTH.DerivingStrategies-translateTHtoGHCExt TH.DerivingVia = GhcTH.DerivingVia-translateTHtoGHCExt TH.TypeSynonymInstances = GhcTH.TypeSynonymInstances-translateTHtoGHCExt TH.FlexibleContexts = GhcTH.FlexibleContexts-translateTHtoGHCExt TH.FlexibleInstances = GhcTH.FlexibleInstances-translateTHtoGHCExt TH.ConstrainedClassMethods = GhcTH.ConstrainedClassMethods-translateTHtoGHCExt TH.MultiParamTypeClasses = GhcTH.MultiParamTypeClasses-translateTHtoGHCExt TH.NullaryTypeClasses = GhcTH.NullaryTypeClasses-translateTHtoGHCExt TH.FunctionalDependencies = GhcTH.FunctionalDependencies-translateTHtoGHCExt TH.UnicodeSyntax = GhcTH.UnicodeSyntax-translateTHtoGHCExt TH.ExistentialQuantification = GhcTH.ExistentialQuantification-translateTHtoGHCExt TH.MagicHash = GhcTH.MagicHash-translateTHtoGHCExt TH.EmptyDataDecls = GhcTH.EmptyDataDecls-translateTHtoGHCExt TH.KindSignatures = GhcTH.KindSignatures-translateTHtoGHCExt TH.RoleAnnotations = GhcTH.RoleAnnotations-translateTHtoGHCExt TH.ParallelListComp = GhcTH.ParallelListComp-translateTHtoGHCExt TH.TransformListComp = GhcTH.TransformListComp-translateTHtoGHCExt TH.MonadComprehensions = GhcTH.MonadComprehensions-translateTHtoGHCExt TH.GeneralizedNewtypeDeriving = GhcTH.GeneralizedNewtypeDeriving-translateTHtoGHCExt TH.RecursiveDo = GhcTH.RecursiveDo-translateTHtoGHCExt TH.PostfixOperators = GhcTH.PostfixOperators-translateTHtoGHCExt TH.TupleSections = GhcTH.TupleSections-translateTHtoGHCExt TH.PatternGuards = GhcTH.PatternGuards-translateTHtoGHCExt TH.LiberalTypeSynonyms = GhcTH.LiberalTypeSynonyms-translateTHtoGHCExt TH.RankNTypes = GhcTH.RankNTypes-translateTHtoGHCExt TH.ImpredicativeTypes = GhcTH.ImpredicativeTypes-translateTHtoGHCExt TH.TypeOperators = GhcTH.TypeOperators-translateTHtoGHCExt TH.ExplicitNamespaces = GhcTH.ExplicitNamespaces-translateTHtoGHCExt TH.PackageImports = GhcTH.PackageImports-translateTHtoGHCExt TH.ExplicitForAll = GhcTH.ExplicitForAll-translateTHtoGHCExt TH.AlternativeLayoutRule = GhcTH.AlternativeLayoutRule-translateTHtoGHCExt TH.AlternativeLayoutRuleTransitional = GhcTH.AlternativeLayoutRuleTransitional-translateTHtoGHCExt TH.DatatypeContexts = GhcTH.DatatypeContexts-translateTHtoGHCExt TH.NondecreasingIndentation = GhcTH.NondecreasingIndentation-translateTHtoGHCExt TH.RelaxedLayout = GhcTH.RelaxedLayout-translateTHtoGHCExt TH.TraditionalRecordSyntax = GhcTH.TraditionalRecordSyntax-translateTHtoGHCExt TH.LambdaCase = GhcTH.LambdaCase-translateTHtoGHCExt TH.MultiWayIf = GhcTH.MultiWayIf-translateTHtoGHCExt TH.BinaryLiterals = GhcTH.BinaryLiterals-translateTHtoGHCExt TH.NegativeLiterals = GhcTH.NegativeLiterals-translateTHtoGHCExt TH.HexFloatLiterals = GhcTH.HexFloatLiterals-translateTHtoGHCExt TH.DuplicateRecordFields = GhcTH.DuplicateRecordFields-translateTHtoGHCExt TH.OverloadedLabels = GhcTH.OverloadedLabels-translateTHtoGHCExt TH.EmptyCase = GhcTH.EmptyCase-translateTHtoGHCExt TH.PatternSynonyms = GhcTH.PatternSynonyms-translateTHtoGHCExt TH.PartialTypeSignatures = GhcTH.PartialTypeSignatures-translateTHtoGHCExt TH.NamedWildCards = GhcTH.NamedWildCards-translateTHtoGHCExt TH.StaticPointers = GhcTH.StaticPointers-translateTHtoGHCExt TH.TypeApplications = GhcTH.TypeApplications-translateTHtoGHCExt TH.Strict = GhcTH.Strict-translateTHtoGHCExt TH.StrictData = GhcTH.StrictData-#if ! MIN_VERSION_ghc(9,2,0)-translateTHtoGHCExt TH.MonadFailDesugaring = GhcTH.MonadFailDesugaring-#endif-translateTHtoGHCExt TH.EmptyDataDeriving = GhcTH.EmptyDataDeriving-translateTHtoGHCExt TH.NumericUnderscores = GhcTH.NumericUnderscores-translateTHtoGHCExt TH.QuantifiedConstraints = GhcTH.QuantifiedConstraints-translateTHtoGHCExt TH.StarIsType = GhcTH.StarIsType--#if MIN_VERSION_ghc(8,10,0)-translateTHtoGHCExt TH.CUSKs = GhcTH.CUSKs-translateTHtoGHCExt TH.ImportQualifiedPost = GhcTH.ImportQualifiedPost-translateTHtoGHCExt TH.UnliftedNewtypes = GhcTH.UnliftedNewtypes-translateTHtoGHCExt TH.StandaloneKindSignatures = GhcTH.StandaloneKindSignatures-#endif-#if MIN_VERSION_ghc(9,0,0)-translateTHtoGHCExt TH.QualifiedDo = GhcTH.QualifiedDo-translateTHtoGHCExt TH.LinearTypes = GhcTH.LinearTypes-translateTHtoGHCExt TH.LexicalNegation = GhcTH.LexicalNegation-#endif-#if MIN_VERSION_ghc(9,2,0)-translateTHtoGHCExt TH.UnliftedDatatypes = GhcTH.UnliftedDatatypes-translateTHtoGHCExt TH.FieldSelectors = GhcTH.FieldSelectors-translateTHtoGHCExt TH.OverloadedRecordDot = GhcTH.OverloadedRecordDot-translateTHtoGHCExt TH.OverloadedRecordUpdate = GhcTH.OverloadedRecordUpdate-#endif
src/PyF/Internal/Parser.hs view
@@ -12,6 +12,12 @@ import Lexer (ParseResult (..)) #endif +#if MIN_VERSION_ghc(9,3,0)+import GHC.Types.Error+import GHC.Utils.Outputable+import GHC.Utils.Error+#endif+ #if MIN_VERSION_ghc(9,2,0) import qualified GHC.Parser.Errors.Ppr as ParserErrorPpr #endif@@ -24,8 +30,10 @@ #if MIN_VERSION_ghc(9,0,0) import GHC.Driver.Session (DynFlags)+import GHC.Types.SrcLoc #else import DynFlags (DynFlags)+import SrcLoc #endif #if MIN_VERSION_ghc(8,10,0)@@ -39,9 +47,9 @@ import qualified PyF.Internal.ParserEx as ParseExp -parseExpression :: String -> DynFlags -> Either (Int, Int, String) (HsExpr GhcPs)-parseExpression s dynFlags =- case ParseExp.parseExpression s dynFlags of+parseExpression :: RealSrcLoc -> String -> DynFlags -> Either (Int, Int, String) (HsExpr GhcPs)+parseExpression initLoc s dynFlags =+ case ParseExp.parseExpression initLoc s dynFlags of POk _ locatedExpr -> let expr = SrcLoc.unLoc locatedExpr in Right@@ -59,11 +67,23 @@ -- TODO: check for pattern failure PFailed _ (SrcLoc.srcSpanEnd -> SrcLoc.RealSrcLoc srcLoc) doc -> #endif-#if MIN_VERSION_ghc(9,2,0)++#if MIN_VERSION_ghc(9,3,0) let+ err = renderWithContext defaultSDocContext+ $ vcat+ $ map (formatBulleted defaultSDocContext)+ $ map diagnosticMessage+ $ map errMsgDiagnostic+ $ sortMsgBag Nothing+ $ getMessages $ errorMessages+ line = SrcLoc.srcLocLine srcLoc+ col = SrcLoc.srcLocCol srcLoc+ in Left (line, col, err)+#elif MIN_VERSION_ghc(9,2,0)+ let psErrToString e = show $ ParserErrorPpr.pprError e err = concatMap psErrToString errorMessages- -- err = concatMap show errorMessages line = SrcLoc.srcLocLine srcLoc col = SrcLoc.srcLocCol srcLoc in Left (line, col, err)
src/PyF/Internal/ParserEx.hs view
@@ -86,6 +86,10 @@ import OccName #endif +#if MIN_VERSION_ghc(9,3,0)+import GHC.Driver.Config.Parser (initParserOpts)+#endif+ import Data.Maybe fakeSettings :: Settings@@ -141,6 +145,10 @@ #if MIN_VERSION_ghc(9, 2, 0) , platform_constants=platformConstants #endif+#if MIN_VERSION_ghc(9, 3, 0)+ , platformHasLibm=True+#endif+ , #endif @@ -173,31 +181,30 @@ -- From Language.Haskell.GhclibParserEx.GHC.Parser -parse :: P a -> String -> DynFlags -> ParseResult a-parse p str flags =+parse :: RealSrcLoc -> P a -> String -> DynFlags -> ParseResult a+parse initLoc p str flags = Lexer.unP p parseState where- location = mkRealSrcLoc (mkFastString "<string>") 1 1 buffer = stringToStringBuffer str parseState = #if MIN_VERSION_ghc(9, 2, 0)- initParserState (initParserOpts flags) buffer location+ initParserState (initParserOpts flags) buffer initLoc #else- mkPState flags buffer location+ mkPState flags buffer initLoc #endif #if MIN_VERSION_ghc(9, 2, 0)-parseExpression :: String -> DynFlags -> ParseResult (LocatedA (HsExpr GhcPs))-parseExpression s flags =- case parse Parser.parseExpression s flags of+parseExpression :: RealSrcLoc -> String -> DynFlags -> ParseResult (LocatedA (HsExpr GhcPs))+parseExpression initLoc s flags =+ case parse initLoc Parser.parseExpression s flags of POk s e -> unP (runPV (unECP e)) s PFailed ps -> PFailed ps #elif MIN_VERSION_ghc(8, 10, 0)-parseExpression :: String -> DynFlags -> ParseResult (Located (HsExpr GhcPs))-parseExpression s flags =- case parse Parser.parseExpression s flags of+parseExpression :: RealSrcLoc -> String -> DynFlags -> ParseResult (Located (HsExpr GhcPs))+parseExpression initLoc s flags =+ case parse initLoc Parser.parseExpression s flags of POk s e -> unP (runECP_P e) s PFailed ps -> PFailed ps #else-parseExpression = parse Parser.parseExpression+parseExpression initLoc = parse initLoc Parser.parseExpression #endif
src/PyF/Internal/PythonSyntax.hs view
@@ -4,6 +4,8 @@ {-# LANGUAGE KindSignatures #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE CPP #-} -- | -- This module provides a parser for <https://docs.python.org/3.4/library/string.html#formatspec python format string mini language>.@@ -26,18 +28,28 @@ import Control.Monad.Reader import qualified Data.Char import Data.Maybe (fromMaybe)-import qualified Language.Haskell.TH.LanguageExtensions as ParseExtension+import GHC (GhcPs, HsExpr)+import Language.Haskell.TH.LanguageExtensions (Extension (..)) import Language.Haskell.TH.Syntax (Exp) import PyF.Formatters import PyF.Internal.Meta import qualified PyF.Internal.Parser as ParseExp import Text.Parsec+import Data.Data (Data) +#if MIN_VERSION_ghc(9,0,0)+import GHC.Types.SrcLoc+import GHC.Data.FastString+#else+import SrcLoc+import FastString+#endif+ type Parser t = ParsecT String () (Reader ParsingContext) t data ParsingContext = ParsingContext { delimiters :: Maybe (Char, Char),- enabledExtensions :: [ParseExtension.Extension]+ enabledExtensions :: [Extension] } deriving (Show) @@ -66,8 +78,7 @@ = -- | A raw string Raw String | -- | A replacement string, composed of an arbitrary Haskell expression followed by an optional formatter- Replacement Exp (Maybe FormatMode)- deriving (Show)+ Replacement (HsExpr GhcPs, Exp) (Maybe FormatMode) -- | -- Parse a string, returns a list of raw string or replacement fields@@ -160,25 +171,23 @@ -- | A Formatter, listing padding, format and and grouping char data FormatMode = FormatMode Padding TypeFormat (Maybe Char)- deriving (Show) -- | Padding, containing the padding width, the padding char and the alignement mode data Padding = PaddingDefault | Padding (ExprOrValue Int) (Maybe (Maybe Char, AnyAlign))- deriving (Show) -- | Represents a value of type @t@ or an Haskell expression supposed to represents that value data ExprOrValue t = Value t- | HaskellExpr Exp- deriving (Show)+ | HaskellExpr (HsExpr GhcPs, Exp)+ deriving (Data) -- | Floating point precision data Precision = PrecisionDefault | Precision (ExprOrValue Int)- deriving (Show)+ deriving (Data) {- @@ -229,29 +238,38 @@ HexCapsF AlternateForm SignMode | -- | Percent representation PercentF Precision AlternateForm SignMode- deriving (Show)+ deriving (Data) -- | If the formatter use its alternate form data AlternateForm = AlternateForm | NormalForm- deriving (Show)+ deriving (Show, Data) -evalExpr :: [ParseExtension.Extension] -> Parser String -> Parser Exp+evalExpr :: [Extension] -> Parser String -> Parser (HsExpr GhcPs, Exp) evalExpr exts exprParser = do+ exprPos <- getPosition+ -- Inject the correct source location in the GHC parser, so it already match+ -- the input source file.+ let initLoc = mkRealSrcLoc (mkFastString (sourceName exprPos)) (sourceLine exprPos) (sourceColumn exprPos) s <- lookAhead exprParser -- Setup the dyn flags using the provided list of extensions- let exts' = fmap translateTHtoGHCExt exts- let dynFlags = baseDynFlags exts'- case ParseExp.parseExpression s dynFlags of+ let dynFlags = baseDynFlags exts+ case ParseExp.parseExpression initLoc s dynFlags of Right expr -> do- -- Consumne the expression+ -- Consume the expression void exprParser- pure (toExp dynFlags expr)+ pure (expr, toExp dynFlags expr) Left (lineError, colError, err) -> do+ -- In case of error, we just advance the parser to the error location.+ -- Note: we have to remove what was introduced in `initLoc` -- Skip lines- replicateM_ (lineError - 1) (manyTill anyChar newline)+ replicateM_ (lineError - sourceLine exprPos) (manyTill anyChar newline) -- Skip columns- void $ count (colError - 2) anyChar-+ -- This is a bit more counter intuitive. If we have skipped not lines, we+ -- must remove the introduced column offset, otherwise no.+ let columnSkip+ | lineError - sourceLine exprPos == 0 = colError - 1 - sourceColumn exprPos+ | otherwise = colError - 2+ void $ count columnSkip anyChar fail $ err <> " in haskell expression" overrideAlignmentIfZero :: Bool -> Maybe (Maybe Char, AnyAlign) -> Maybe (Maybe Char, AnyAlign)@@ -289,8 +307,8 @@ exts <- asks enabledExtensions Just (charOpening, charClosing) <- asks delimiters choice- [ Value <$> width- , char charOpening *> (HaskellExpr <$> evalExpr exts (someTill (satisfy (/= charClosing)) (char charClosing) <?> "an haskell expression"))+ [ Value <$> width,+ char charOpening *> (HaskellExpr <$> evalExpr exts (someTill (satisfy (/= charClosing)) (char charClosing) <?> "an haskell expression")) ] parsePrecision :: Parser Precision@@ -346,7 +364,7 @@ where showExpr = case e of Value v -> show v- HaskellExpr expr -> show expr+ HaskellExpr (_, expr) -> show expr failIfAlt :: AlternateForm -> TypeFormat -> Either String TypeFormat failIfAlt NormalForm i = Right i
src/PyF/Internal/QQ.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DisambiguateRecordFields #-} {-# LANGUAGE FlexibleContexts #-}@@ -13,6 +14,7 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns #-}+{-# OPTIONS_GHC -Wno-name-shadowing #-} -- | This module uses the python mini language detailed in -- 'PyF.Internal.PythonSyntax' to build an template haskell expression@@ -26,20 +28,84 @@ where import Control.Monad.Reader+import Data.Data (Data (gmapQ), Typeable, cast) import Data.Kind-import Data.Maybe (fromMaybe)+import Data.List (intercalate)+import Data.Maybe (catMaybes, fromMaybe) import Data.Proxy import Data.String (fromString)+import GHC (GenLocated (L))++#if MIN_VERSION_ghc(9,0,0)+import GHC.Tc.Utils.Monad (addErrAt)+import GHC.Tc.Types (TcM)+import GHC.Tc.Gen.Splice (lookupThName_maybe)+#else+import TcRnTypes (TcM)+import TcSplice (lookupThName_maybe)+import TcRnMonad (addErrAt)+#endif++#if MIN_VERSION_ghc(9,3,0)+import GHC.Tc.Errors.Types+import GHC.Types.Error+import GHC.Driver.Errors.Types+import GHC.Parser.Errors.Types+import GHC.Utils.Outputable (text)+#endif++++#if MIN_VERSION_ghc(9,0,0)+import GHC.Types.Name.Reader+#else+import FastString+import RdrName+#endif++#if MIN_VERSION_ghc(8,10,0)+import GHC.Hs.Expr as Expr+import GHC.Hs.Extension as Ext+import GHC.Hs.Pat as Pat+#else+import HsExpr as Expr+import HsExtension as Ext+import HsPat as Pat+import HsLit+#endif++#if MIN_VERSION_ghc(9,0,0)+import GHC.Types.SrcLoc+#else+import SrcLoc+#endif++#if MIN_VERSION_ghc(8,10,0)+import GHC.Hs+#else+import HsSyn+#endif+ import GHC.TypeLits import Language.Haskell.TH hiding (Type) import Language.Haskell.TH.Quote+import Language.Haskell.TH.Syntax (Q (Q)) import PyF.Class import PyF.Formatters (AnyAlign (..)) import qualified PyF.Formatters as Formatters+import PyF.Internal.Meta (toName) import PyF.Internal.PythonSyntax import Text.Parsec-import Text.Parsec.Error (errorMessages, messageString, setErrorPos, showErrorMessages)+import Text.Parsec.Error+ ( errorMessages,+ messageString,+ newErrorMessage,+ setErrorPos,+ showErrorMessages,+ )+import Text.Parsec.Pos (newPos, initialPos) import Text.ParserCombinators.Parsec.Error (Message (..))+import Unsafe.Coerce (unsafeCoerce) -- | Configuration for the quasiquoter data Config = Config@@ -77,51 +143,129 @@ -- | Parse a string and return a formatter for it toExp :: Config -> String -> Q Exp toExp Config {delimiters = expressionDelimiters, postProcess} s = do- filename <- loc_filename <$> location+ loc <- location exts <- extsEnabled let context = ParsingContext expressionDelimiters exts- case runReader (runParserT parseGenericFormatString () filename s) context of++ -- Setup the parser so it matchs the real original position in the source+ -- code.+ let filename = loc_filename loc+ let initPos = setSourceColumn (setSourceLine (initialPos filename) (fst $ loc_start loc)) (snd $ loc_start loc)+ case runReader (runParserT (setPosition initPos >> parseGenericFormatString) () filename s) context of Left err -> do- err' <- overrideErrorForFile filename err- fail =<< prettyError filename s err'- Right items -> postProcess (goFormat items)+ reportParserErrorAt err+ -- returns a dummy exp, so TH continues its life. This TH code won't be+ -- executed anyway, there is an error+ [|()|]+ Right items -> do+ checkResult <- checkVariables items+ case checkResult of+ Nothing -> postProcess (goFormat items)+ Just (srcSpan, msg) -> do+ reportErrorAt srcSpan msg+ [|()|] --- | Display a pretty version of an error, with caret and file context.-prettyError ::- -- | Filename of the file which contains the error- FilePath ->- -- | Content of the file- String ->- -- | Parse error from parsec- ParseError ->- Q String-prettyError filename s err = do- let sourceLoc = errorPos err- line = sourceLine sourceLoc- column = sourceColumn sourceLoc- name = sourceName sourceLoc- carretOffset = column - 1- carret = replicate carretOffset ' ' <> "^"- colIndicator = show line <> " | "- colPrefix = replicate (length (show line)) ' ' <> " |"+findFreeVariablesInFormatMode :: Maybe FormatMode -> [(SrcSpan, RdrName)]+findFreeVariablesInFormatMode Nothing = []+findFreeVariablesInFormatMode (Just (FormatMode padding tf _ )) = findFreeVariables tf <> case padding of+ PaddingDefault -> []+ Padding eoi _ -> findFreeVariables eoi - code <- case filename of- -- If that's an interectavi file, we don't know much, so just dump the string.- "<interactive>" -> pure s- _ -> do- content <- runIO (readFile filename)- pure $ lines content !! (line - 1)+checkOneItem :: Item -> Q (Maybe (SrcSpan, String))+checkOneItem (Raw _) = pure Nothing+checkOneItem (Replacement (hsExpr, _) formatMode) = do+ let allNames = findFreeVariables hsExpr <> findFreeVariablesInFormatMode formatMode+ res <- mapM doesExists allNames+ let resFinal = catMaybes res - pure $- unlines $- [ name <> ":" <> show line <> ":" <> show column <> ":",- colPrefix,- colIndicator <> code,- colPrefix <> " " <> carret- ]- ++ formatErrorMessages err+ case resFinal of+ [] -> pure Nothing+ ((err, span) : _) -> pure $ Just (span, err) --- | Format a bunch of error++findFreeVariables :: Data a => a -> [(SrcSpan, RdrName)]+findFreeVariables item = allNames+ where+ -- Find all free Variables in an HsExpr+ f :: forall a. (Data a, Typeable a) => a -> [Located RdrName]+ f e = case cast @_ @(HsExpr GhcPs) e of+#if MIN_VERSION_ghc(9,2,0)+ Just (HsVar _ l@(L a b)) -> [L (locA a) (unLoc l)]+#else+ Just (HsVar _ l) -> [l]+#endif+ Just (HsLam _ (MG _ (unLoc -> (map unLoc -> [Expr.Match _ _ (map unLoc -> ps) (GRHSs _ [unLoc -> GRHS _ _ (unLoc -> e)] _)])) _)) -> filter keepVar subVars+ where+ keepVar (L _ n) = n `notElem` subPats+ subVars = concat $ gmapQ f [e]+ subPats = concat $ gmapQ findPats ps+ _ -> concat $ gmapQ f e++ -- Find all Variables bindings (i.e. patterns) in an HsExpr+ findPats :: forall a. (Data a, Typeable a) => a -> [RdrName]+ findPats p = case cast @_ @(Pat.Pat GhcPs) p of+ Just (VarPat _ (unLoc -> name)) -> [name]+ _ -> concat $ gmapQ findPats p+ -- Be careful, we wrap hsExpr in a list, so the toplevel hsExpr will be+ -- seen by gmapQ. Otherwise it will miss variables if they are the top+ -- level expression: gmapQ only checks sub constructors.+ allVars = concat $ gmapQ f [item]+ allNames = map (\(L l e) -> (l, e)) allVars++doesExists :: (b, RdrName) -> Q (Maybe (String, b))+doesExists (loc, name) = do+ res <- unsafeRunTcM $ lookupThName_maybe (toName name)+ case res of+ Nothing -> pure (Just ("Variable not in scope: " <> show (toName name), loc))+ Just _ -> pure Nothing++-- | Check that all variables used in 'Item' exists, otherwise, fail.+checkVariables :: [Item] -> Q (Maybe (SrcSpan, String))+checkVariables [] = pure Nothing+checkVariables (x : xs) = do+ r <- checkOneItem x+ case r of+ Nothing -> checkVariables xs+ Just err -> pure $ Just err++-- Stolen from: https://www.tweag.io/blog/2021-01-07-haskell-dark-arts-part-i/+-- This allows to hack inside the the GHC api and use function not exported by template haskell.+unsafeRunTcM :: TcM a -> Q a+unsafeRunTcM m = Q (unsafeCoerce m)++-- | This function is similar to TH reportError, however it also provide+-- correct SrcSpan, so error are localised at the correct position in the TH+-- splice instead of being at the beginning.+reportErrorAt :: SrcSpan -> String -> Q ()+reportErrorAt loc msg = unsafeRunTcM $ addErrAt loc msg'+ where+#if MIN_VERSION_ghc(9,3,0)+ msg' = TcRnUnknownMessage (GhcPsMessage $ PsUnknownMessage $ mkPlainError noHints $+ text msg)+#else+ msg' = fromString msg+#endif++reportParserErrorAt :: ParseError -> Q ()+reportParserErrorAt err = reportErrorAt span msg+ where+ msg = intercalate "\n" $ formatErrorMessages err++ span :: SrcSpan+ span = mkSrcSpan loc loc'++ loc = srcLocFromParserError (errorPos err)+ loc' = srcLocFromParserError (incSourceColumn (errorPos err) 1)++srcLocFromParserError :: SourcePos -> SrcLoc+srcLocFromParserError sourceLoc = srcLoc+ where+ line = sourceLine sourceLoc+ column = sourceColumn sourceLoc+ name = sourceName sourceLoc++ srcLoc = mkSrcLoc (fromString name) line column+ formatErrorMessages :: ParseError -> [String] formatErrorMessages err -- If there is an explicit error message from parsec, use only that@@ -132,24 +276,6 @@ (_sysUnExpect, msgs1) = span (SysUnExpect "" ==) (errorMessages err) (_unExpect, msgs2) = span (UnExpect "" ==) msgs1 (_expect, messages) = span (Expect "" ==) msgs2---- Parsec displays error relative to what they parsed--- However the formatting string is part of a more complex file and we--- want error reporting relative to that file-overrideErrorForFile :: FilePath -> ParseError -> Q ParseError--- We have no may to recover interactive content--- So we won't do better than displaying the Parsec--- error relative to the quasi quote content-overrideErrorForFile "<interactive>" err = pure err--- We know the content of the file here-overrideErrorForFile _ err = do- (line, col) <- loc_start <$> location- let sourcePos = errorPos err- sourcePos'- | sourceLine sourcePos == 1 = incSourceColumn (incSourceLine sourcePos (line - 1)) (col - 1)- | otherwise = setSourceColumn (incSourceLine sourcePos (line - 1)) (sourceColumn sourcePos)- pure $ setErrorPos sourcePos' err- {- Note: Empty String Lifting @@ -169,7 +295,7 @@ toFormat :: Item -> Q Exp toFormat (Raw x) = pure $ LitE (StringL x) -- see [Empty String Lifting]-toFormat (Replacement expr y) = do+toFormat (Replacement ( _, expr) y) = do formatExpr <- padAndFormat (fromMaybe DefaultFormatMode y) pure (formatExpr `AppE` expr) @@ -223,7 +349,7 @@ exprToInt :: ExprOrValue Int -> Q Exp -- Note: this is a literal provided integral. We use explicit case to ::Int so it won't warn about defaulting exprToInt (Value i) = [|$(pure $ LitE (IntegerL (fromIntegral i))) :: Int|]-exprToInt (HaskellExpr e) = [|$(pure e)|]+exprToInt (HaskellExpr (_, e)) = [|$(pure e)|] data PaddingK k i where PaddingDefaultK :: PaddingK 'Formatters.AlignAll Int
test/Spec.hs view
@@ -3,13 +3,18 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE ExtendedDefaultRules #-}+{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} -- This warning is disabled because any expression with literal leads to it. {-# OPTIONS -Wno-type-defaults #-}@@ -19,10 +24,13 @@ import qualified Data.ByteString.Lazy import qualified Data.ByteString.Lazy.Char8 import qualified Data.List as List+import Data.Proxy (Proxy (..)) import qualified Data.Ratio import qualified Data.Text import qualified Data.Text.Lazy import qualified Data.Time+import GHC.OverloadedLabels+import GHC.TypeLits (KnownSymbol, Symbol, symbolVal) import PyF import SpecCustomDelimiters import SpecUtils@@ -60,6 +68,20 @@ type instance PyFClassify FooDefault = 'PyFString +-- Data type to test overloaded labels+data V (a :: Symbol) = V++instance KnownSymbol a => Show (V a) where+ show V = "V=" ++ symbolVal (Proxy @a)++instance (a ~ a') => IsLabel a (V a') where+ fromLabel = V++showV :: KnownSymbol a => V a -> String+showV = show++globalName = "Valérian"+ spec :: Spec spec = do describe "simple with external variable" $ do@@ -243,8 +265,8 @@ do let n = 3 :: Int [fmt|{pi:.{n}}|] `shouldBe` "3.142"- describe "variable padding" $ - it "works" $ + describe "variable padding" $+ it "works" $ do let n = 5 :: Integer [fmt|Bonjour {'a':>{n}}|] `shouldBe` "Bonjour a"@@ -302,6 +324,8 @@ [fmt|hello {show @_ 10}|] `shouldBe` "hello 10" it "parses BinaryLiterals" $ [fmt|hello {0b1111}|] `shouldBe` "hello 15"+ it "OverloadedLabels works" $+ [fmt|{showV #abc}|] `shouldBe` "V=abc" describe "custom types" $ do it "works with integral" $ [fmt|{FooIntegral 10:d}|] `shouldBe` "10"@@ -316,6 +340,11 @@ let fooDouble = FooFloating (100.123 :: Double) in [fmt|{fooDouble}|] `shouldBe` "100.123" let fooFloat = FooFloating (100.123 :: Float) in [fmt|{fooFloat}|] `shouldBe` "100.123" [fmt|{FooDefault}|] `shouldBe` "FooDefault"+ describe "Special syntax " $ do+ it "[] is correct expression" $ do+ [fmt|{[] @Char}|] `shouldBe` ""+ it "() is correct expression" $ do+ [fmt|{const "STRING" ()}|] `shouldBe` "STRING" describe "instances" $ do describe "default" $ do@@ -502,3 +531,18 @@ [fmt|{-10 :: Int::>10d}|] `shouldBe` ":::::::-10" it "works in a padding ^ context" $ do [fmt|{-10 :: Int::^10d}|] `shouldBe` ":::-10::::"++ describe "variables" $ do+ it "local" $ do+ let var = "Guillaume" :: String+ [fmt|{var}|] `shouldBe` "Guillaume"+ it "global" $ do+ [fmt|{globalName}|] `shouldBe` "Valérian"+ it "multiple expressions with variables" $ do+ let padding = 10+ let precision = 3+ [fmt|{globalName:{padding}} and pi = {pi:.{precision}}|] `shouldBe` "Valérian and pi = 3.142"+ it "an expression with multiples variables" $ do+ let padding = 10+ let precision = 3+ [fmt|pi = {pi:{padding}.{precision}}|] `shouldBe` "pi = 3.142"
test/SpecFail.hs view
@@ -1,9 +1,12 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE ExtendedDefaultRules #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE QuasiQuotes #-} import Control.DeepSeq import Control.Exception+import Data.Bits (Bits (..))+import Data.Char (ord) import qualified Data.Text as Text import System.Exit import System.FilePath@@ -13,6 +16,8 @@ import Test.HUnit.Lang import Test.Hspec +import PyF+ -- * Check compilation with external GHC (this is usefull to test compilation failure) data CompilationStatus@@ -22,8 +27,16 @@ | Ok String deriving (Show, Eq) + makeTemplate :: String -> String-makeTemplate s = "{-# LANGUAGE QuasiQuotes, ExtendedDefaultRules, TypeApplications #-}\nimport PyF\ntruncate' = truncate @Float @Int\nhello = \"hello\"\nnumber = 3.14 :: Float\nmain :: IO ()\nmain = putStrLn [fmt|" ++ s ++ "|]\n"+makeTemplate s = [fmt|\+{{-# LANGUAGE QuasiQuotes, ExtendedDefaultRules, TypeApplications #-}}+import PyF+truncate' = truncate @Float @Int+hello = "hello"+number = 3.14 :: Float+main :: IO ()+main = putStrLn [fmt|{s}|] <> "|]\n" -- | Compile a formatting string --@@ -107,17 +120,28 @@ failCompileContent :: HasCallStack => String -> String -> String -> Spec failCompileContent h caption fileContent = before (checkCompile fileContent) $ do- let goldenPath = concatMap cleanSpecialChars h+ let goldenName = concatMap cleanSpecialChars h+ -- Add an unique identifier, so golden files won't conflict on case+ -- insensitive systems+ -- See: bug #97.+ goldenPath = goldenName ++ "." ++ show (stableHash goldenName) it (show caption) $ \res -> case res of CompileError output -> golden goldenPath output _ -> assertFailure (show $ ".golden/" <> goldenPath <> "\n" <> show res) +-- | A stable hash from string, based on+-- https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1_hash+stableHash :: String -> Word+stableHash [] = 14695981039346656037+stableHash (x : xs) = fromIntegral (ord x) * stableHash xs `xor` 1099511628211+ -- Remove chars which are not accepted in a path name+-- The encoding is rather approximative, I'm trying to avoid too long names. cleanSpecialChars :: Char -> [Char]-cleanSpecialChars '/' = "SLASH"-cleanSpecialChars '\\' = "BACKSLASH"-cleanSpecialChars ':' = "COLON"-cleanSpecialChars '\n' = "NEWLINE"+cleanSpecialChars '/' = "SL"+cleanSpecialChars '\\' = "BS"+cleanSpecialChars ':' = "CL"+cleanSpecialChars '\n' = "NL" cleanSpecialChars e = pure e main :: IO ()@@ -195,3 +219,10 @@ failCompile "{True}" failCompile "{True:f}" failCompile "{True:d}"+ describe "Missing variables" $ do+ failCompile "Hello {name}"+ failCompile "Hello {length name}"+ failCompile "Hello {pi:.{precision}}"+ failCompile "Hello {pi:.{truncate number + precision}}"+ failCompile "Hello {pi:.{precision}}"+ failCompile "Hello {pi:{width}}"
+ test/golden/Hello {length name}.16675806454852491955.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:36: error:+ • Variable not in scope: name+ • In the quasi-quotation: [fmt|Hello {length name}|]+ |+7 | main = putStrLn [fmt|Hello {length name}|]+ | ^^^^
+ test/golden/Hello {name}.16618004304593959603.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:29: error:+ • Variable not in scope: name+ • In the quasi-quotation: [fmt|Hello {name}|]+ |+7 | main = putStrLn [fmt|Hello {name}|]+ | ^^^^
+ test/golden/Hello {piCL.{precision}}.9628757040831863475.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:34: error:+ • Variable not in scope: precision+ • In the quasi-quotation: [fmt|Hello {pi:.{precision}}|]+ |+7 | main = putStrLn [fmt|Hello {pi:.{precision}}|]+ | ^^^^^^^^^
+ test/golden/Hello {piCL.{truncate number + precision}}.18094049741103110835.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:52: error:+ • Variable not in scope: precision+ • In the quasi-quotation: [fmt|Hello {pi:.{truncate number + precision}}|]+ |+7 | main = putStrLn [fmt|Hello {pi:.{truncate number + precision}}|]+ | ^^^^^^^^^
+ test/golden/Hello {piCL{width}}.15463239215289408179.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:33: error:+ • Variable not in scope: width+ • In the quasi-quotation: [fmt|Hello {pi:{width}}|]+ |+7 | main = putStrLn [fmt|Hello {pi:{width}}|]+ | ^^^^^
− test/golden/fooBACKSLASHPbar.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:25:- |-7 | main = putStrLn [fmt|foo\Pbar|]- | ^-Lexical error in literal section-- • In the quasi-quotation: [fmt|foo\Pbar|]- |-7 | main = putStrLn [fmt|foo\Pbar|]- | ^^^^^^^^^^
+ test/golden/fooBSPbar.17645057532673886893.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:25: error:+ • Lexical error in literal section+ • In the quasi-quotation: [fmt|foo\Pbar|]+ |+7 | main = putStrLn [fmt|foo\Pbar|]+ | ^
− test/golden/fooNEWLINEbliBACKSLASHPbar.golden
@@ -1,13 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:8:4:- |-8 | bli\Pbar|]- | ^-Lexical error in literal section-- • In the quasi-quotation: [fmt|foo-bli\Pbar|]- |-7 | main = putStrLn [fmt|foo- | ^^^...
+ test/golden/fooNLbliBSPbar.16759496276764189145.golden view
@@ -0,0 +1,8 @@++INITIALPATH:8:4: error:+ • Lexical error in literal section+ • In the quasi-quotation: [fmt|foo+bli\Pbar|]+ |+8 | bli\Pbar|]+ | ^
+ test/golden/hello { world.10778336899993839283.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:35: error:+ • +unexpected end of input+expecting "::", ":" or "}"+ • In the quasi-quotation: [fmt|hello { world|]+ |+7 | main = putStrLn [fmt|hello { world|]+ | ^
− test/golden/hello { world.golden
@@ -1,14 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:35:- |-7 | main = putStrLn [fmt|hello { world|]- | ^--unexpected end of input-expecting "::", ":" or "}"-- • In the quasi-quotation: [fmt|hello { world|]- |-7 | main = putStrLn [fmt|hello { world|]- | ^^^^^^^^^^^^^^^
+ test/golden/hello } world.5295037443422799539.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:28: error:+ • +unexpected '}'+expecting "{{", "}}", "{" or end of input+ • In the quasi-quotation: [fmt|hello } world|]+ |+7 | main = putStrLn [fmt|hello } world|]+ | ^
− test/golden/hello } world.golden
@@ -1,14 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:28:- |-7 | main = putStrLn [fmt|hello } world|]- | ^--unexpected '}'-expecting "{{", "}}", "{" or end of input-- • In the quasi-quotation: [fmt|hello } world|]- |-7 | main = putStrLn [fmt|hello } world|]- | ^^^^^^^^^^^^^^^
− test/golden/helloNEWLINE {NEWLINElet a = 5NEWLINE b = 10NEWLINEin 1 + - SLASH lalalal}.golden
@@ -1,16 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:11:10:- |-11 | in 1 + - / lalalal}|]- | ^-parse error on input `/' in haskell expression-- • In the quasi-quotation: [fmt|hello- {-let a = 5- b = 10-in 1 + - / lalalal}|]- |-7 | main = putStrLn [fmt|hello- | ^^^^^...
− test/golden/helloNEWLINENEWLINENEWLINE{piCOLONl}.golden
@@ -1,17 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:10:6:- |-10 | {pi:l}|]- | ^--unexpected "}"-expecting "<", ">", "^" or "="-- • In the quasi-quotation: [fmt|hello---{pi:l}|]- |-7 | main = putStrLn [fmt|hello- | ^^^^^...
+ test/golden/helloNL {NLlet a = 5NL b = 10NLin 1 + - SL lalalal}.3018767237106994099.golden view
@@ -0,0 +1,11 @@++INITIALPATH:11:10: error:+ • parse error on input `/' in haskell expression+ • In the quasi-quotation: [fmt|hello+ {+let a = 5+ b = 10+in 1 + - / lalalal}|]+ |+11 | in 1 + - / lalalal}|]+ | ^
+ test/golden/helloNLNLNL{piCLl}.13123157148160021427.golden view
@@ -0,0 +1,12 @@++INITIALPATH:10:6: error:+ • +unexpected "}"+expecting "<", ">", "^" or "="+ • In the quasi-quotation: [fmt|hello+++{pi:l}|]+ |+10 | {pi:l}|]+ | ^
+ test/golden/{1 + - SL lalalal}.14923086665437293731.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:29: error:+ • parse error on input `/' in haskell expression+ • In the quasi-quotation: [fmt|{1 + - / lalalal}|]+ |+7 | main = putStrLn [fmt|{1 + - / lalalal}|]+ | ^
− test/golden/{1 + - SLASH lalalal}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:29:- |-7 | main = putStrLn [fmt|{1 + - / lalalal}|]- | ^-parse error on input `/' in haskell expression-- • In the quasi-quotation: [fmt|{1 + - / lalalal}|]- |-7 | main = putStrLn [fmt|{1 + - / lalalal}|]- | ^^^^^^^^^^^^^^^^^^^
+ test/golden/{TrueCLd}.12627313193367841398.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral Bool) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) True)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) True)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) True)+ |+7 | main = putStrLn [fmt|{True:d}|]+ | ^^^^^^^^^^
+ test/golden/{TrueCLf}.18281408089045870326.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Real Bool) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’+ • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) True)’+ In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) True)+ In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) True)+ |+7 | main = putStrLn [fmt|{True:f}|]+ | ^^^^^^^^^^
− test/golden/{TrueCOLONd}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral Bool) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) True)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) True)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) True)- |-7 | main = putStrLn [fmt|{True:d}|]- | ^^^^^^^^^^
− test/golden/{TrueCOLONf}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Real Bool) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’- • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) True)’- In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) True)- In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) True)- |-7 | main = putStrLn [fmt|{True:f}|]- | ^^^^^^^^^^
+ test/golden/{True}.16254223077612353942.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (PyF.Internal.QQ.FormatAny2 (PyFClassify Bool) Bool 'PyF.Formatters.AlignAll) arising from a use of ‘PyF.Internal.QQ.formatAny’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) PyF.Internal.QQ.PaddingDefaultK) Nothing) (Nothing :: Maybe Int)) True)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) PyF.Internal.QQ.PaddingDefaultK) Nothing) (Nothing :: Maybe Int)) True)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) PyF.Internal.QQ.PaddingDefaultK) Nothing) (Nothing :: Maybe Int)) True)+ |+7 | main = putStrLn [fmt|{True}|]+ | ^^^^^^^^
− test/golden/{True}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (PyF.Internal.QQ.FormatAny2 (PyFClassify Bool) Bool 'PyF.Formatters.AlignAll) arising from a use of ‘PyF.Internal.QQ.formatAny’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) PyF.Internal.QQ.PaddingDefaultK) Nothing) (Nothing :: Maybe Int)) True)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) PyF.Internal.QQ.PaddingDefaultK) Nothing) (Nothing :: Maybe Int)) True)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) PyF.Internal.QQ.PaddingDefaultK) Nothing) (Nothing :: Maybe Int)) True)- |-7 | main = putStrLn [fmt|{True}|]- | ^^^^^^^^
+ test/golden/{helloCL s}.13047921915648718386.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:30: error:+ • Type incompatible with sign field ( ), use any of {'b', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 'x', 'X', '%'} or remove the sign field.+ • In the quasi-quotation: [fmt|{hello: s}|]+ |+7 | main = putStrLn [fmt|{hello: s}|]+ | ^
+ test/golden/{helloCL%}.1257653362598537778.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’+ • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Percent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’+ In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Percent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Percent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ |+7 | main = putStrLn [fmt|{hello:%}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCL+s}.1657517030647448626.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:30: error:+ • Type incompatible with sign field (+), use any of {'b', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 'x', 'X', '%'} or remove the sign field.+ • In the quasi-quotation: [fmt|{hello:+s}|]+ |+7 | main = putStrLn [fmt|{hello:+s}|]+ | ^
+ test/golden/{helloCL,s}.14139635988852178482.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:30: error:+ • String type is incompatible with grouping (_ or ,).+ • In the quasi-quotation: [fmt|{hello:,s}|]+ |+7 | main = putStrLn [fmt|{hello:,s}|]+ | ^
+ test/golden/{helloCL-s}.12627805606214404146.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:30: error:+ • Type incompatible with sign field (-), use any of {'b', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 'x', 'X', '%'} or remove the sign field.+ • In the quasi-quotation: [fmt|{hello:-s}|]+ |+7 | main = putStrLn [fmt|{hello:-s}|]+ | ^
+ test/golden/{helloCL=100s}.14374776122070431282.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:33: error:+ • String type is incompatible with inside padding (=).+ • In the quasi-quotation: [fmt|{hello:=100s}|]+ |+7 | main = putStrLn [fmt|{hello:=100s}|]+ | ^
+ test/golden/{helloCL=100}.9444838110946424370.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • String type is incompatible with inside padding (=).+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) ((PyF.Internal.QQ.PaddingK (100 :: Int)) (Just (Nothing, PyF.Formatters.AlignInside)))) Nothing) (Nothing :: Maybe Int)) hello)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) ((PyF.Internal.QQ.PaddingK (100 :: Int)) (Just (Nothing, PyF.Formatters.AlignInside)))) Nothing) (Nothing :: Maybe Int)) hello)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) ((PyF.Internal.QQ.PaddingK (100 :: Int)) (Just (Nothing, PyF.Formatters.AlignInside)))) Nothing) (Nothing :: Maybe Int)) hello)+ |+7 | main = putStrLn [fmt|{hello:=100}|]+ | ^^^^^^^^^^^^^^
+ test/golden/{helloCLE}.15676531368138664498.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’+ • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Exponent)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’+ In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Exponent)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Exponent)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ |+7 | main = putStrLn [fmt|{hello:E}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLG}.17442699390234010162.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’+ • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Generic)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’+ In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Generic)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Generic)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ |+7 | main = putStrLn [fmt|{hello:G}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLX}.8447528333473699378.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ |+7 | main = putStrLn [fmt|{hello:X}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCL_s}.1094067961907256370.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:30: error:+ • String type is incompatible with grouping (_ or ,).+ • In the quasi-quotation: [fmt|{hello:_s}|]+ |+7 | main = putStrLn [fmt|{hello:_s}|]+ | ^
+ test/golden/{helloCLb}.14869862508711808562.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ |+7 | main = putStrLn [fmt|{hello:b}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLd}.1892681375540151858.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ |+7 | main = putStrLn [fmt|{hello:d}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLe}.13933826712837941810.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’+ • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Exponent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’+ In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Exponent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Exponent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ |+7 | main = putStrLn [fmt|{hello:e}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLf}.14332487603622862386.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’+ • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’+ In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ |+7 | main = putStrLn [fmt|{hello:f}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLg}.9607247906229690930.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’+ • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Generic) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’+ In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Generic) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Generic) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)+ |+7 | main = putStrLn [fmt|{hello:g}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLo}.9389880575827657266.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ |+7 | main = putStrLn [fmt|{hello:o}|]+ | ^^^^^^^^^^^
+ test/golden/{helloCLx}.14710080644372944434.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)+ |+7 | main = putStrLn [fmt|{hello:x}|]+ | ^^^^^^^^^^^
− test/golden/{helloCOLON s}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:30:- |-7 | main = putStrLn [fmt|{hello: s}|]- | ^-Type incompatible with sign field ( ), use any of {'b', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 'x', 'X', '%'} or remove the sign field.-- • In the quasi-quotation: [fmt|{hello: s}|]- |-7 | main = putStrLn [fmt|{hello: s}|]- | ^^^^^^^^^^^^
− test/golden/{helloCOLON%}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’- • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Percent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’- In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Percent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Percent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- |-7 | main = putStrLn [fmt|{hello:%}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLON+s}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:30:- |-7 | main = putStrLn [fmt|{hello:+s}|]- | ^-Type incompatible with sign field (+), use any of {'b', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 'x', 'X', '%'} or remove the sign field.-- • In the quasi-quotation: [fmt|{hello:+s}|]- |-7 | main = putStrLn [fmt|{hello:+s}|]- | ^^^^^^^^^^^^
− test/golden/{helloCOLON,s}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:30:- |-7 | main = putStrLn [fmt|{hello:,s}|]- | ^-String type is incompatible with grouping (_ or ,).-- • In the quasi-quotation: [fmt|{hello:,s}|]- |-7 | main = putStrLn [fmt|{hello:,s}|]- | ^^^^^^^^^^^^
− test/golden/{helloCOLON-s}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:30:- |-7 | main = putStrLn [fmt|{hello:-s}|]- | ^-Type incompatible with sign field (-), use any of {'b', 'd', 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'o', 'x', 'X', '%'} or remove the sign field.-- • In the quasi-quotation: [fmt|{hello:-s}|]- |-7 | main = putStrLn [fmt|{hello:-s}|]- | ^^^^^^^^^^^^
− test/golden/{helloCOLON=100s}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:33:- |-7 | main = putStrLn [fmt|{hello:=100s}|]- | ^-String type is incompatible with inside padding (=).-- • In the quasi-quotation: [fmt|{hello:=100s}|]- |-7 | main = putStrLn [fmt|{hello:=100s}|]- | ^^^^^^^^^^^^^^^
− test/golden/{helloCOLON=100}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • String type is incompatible with inside padding (=).- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) ((PyF.Internal.QQ.PaddingK (100 :: Int)) (Just (Nothing, PyF.Formatters.AlignInside)))) Nothing) (Nothing :: Maybe Int)) hello)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) ((PyF.Internal.QQ.PaddingK (100 :: Int)) (Just (Nothing, PyF.Formatters.AlignInside)))) Nothing) (Nothing :: Maybe Int)) hello)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAny PyF.Formatters.Minus) ((PyF.Internal.QQ.PaddingK (100 :: Int)) (Just (Nothing, PyF.Formatters.AlignInside)))) Nothing) (Nothing :: Maybe Int)) hello)- |-7 | main = putStrLn [fmt|{hello:=100}|]- | ^^^^^^^^^^^^^^
− test/golden/{helloCOLONE}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’- • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Exponent)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’- In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Exponent)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Exponent)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- |-7 | main = putStrLn [fmt|{hello:E}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONG}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’- • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Generic)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’- In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Generic)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional (PyF.Formatters.Upper PyF.Formatters.Generic)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- |-7 | main = putStrLn [fmt|{hello:G}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONX}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- |-7 | main = putStrLn [fmt|{hello:X}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLON_s}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:30:- |-7 | main = putStrLn [fmt|{hello:_s}|]- | ^-String type is incompatible with grouping (_ or ,).-- • In the quasi-quotation: [fmt|{hello:_s}|]- |-7 | main = putStrLn [fmt|{hello:_s}|]- | ^^^^^^^^^^^^
− test/golden/{helloCOLONb}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- |-7 | main = putStrLn [fmt|{hello:b}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONd}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- |-7 | main = putStrLn [fmt|{hello:d}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONe}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’- • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Exponent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’- In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Exponent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Exponent) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- |-7 | main = putStrLn [fmt|{hello:e}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONf}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’- • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’- In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Fixed) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- |-7 | main = putStrLn [fmt|{hello:f}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONg}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Real String) arising from a use of ‘PyF.Internal.QQ.formatAnyFractional’- • In the first argument of ‘putStrLn’, namely ‘((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Generic) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)’- In the expression: putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Generic) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- In an equation for ‘main’: main = putStrLn ((((((PyF.Internal.QQ.formatAnyFractional PyF.Formatters.Generic) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) (Just 6 :: Maybe Int)) hello)- |-7 | main = putStrLn [fmt|{hello:g}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONo}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- |-7 | main = putStrLn [fmt|{hello:o}|]- | ^^^^^^^^^^^
− test/golden/{helloCOLONx}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral String) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) hello)- |-7 | main = putStrLn [fmt|{hello:x}|]- | ^^^^^^^^^^^
+ test/golden/{numberCLX}.4609648040604121432.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ |+7 | main = putStrLn [fmt|{number:X}|]+ | ^^^^^^^^^^^^
+ test/golden/{numberCLb}.8801685868342243288.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ |+7 | main = putStrLn [fmt|{number:b}|]+ | ^^^^^^^^^^^^
+ test/golden/{numberCLd}.13336740346716692056.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ |+7 | main = putStrLn [fmt|{number:d}|]+ | ^^^^^^^^^^^^
+ test/golden/{numberCLo}.12467189151987896600.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ |+7 | main = putStrLn [fmt|{number:o}|]+ | ^^^^^^^^^^^^
+ test/golden/{numberCLx}.14457861675063419224.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:22: error:+ • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’+ • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’+ In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)+ |+7 | main = putStrLn [fmt|{number:x}|]+ | ^^^^^^^^^^^^
− test/golden/{numberCOLONX}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral (PyF.Formatters.Upper PyF.Formatters.Hexa)) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- |-7 | main = putStrLn [fmt|{number:X}|]- | ^^^^^^^^^^^^
− test/golden/{numberCOLONb}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Binary) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- |-7 | main = putStrLn [fmt|{number:b}|]- | ^^^^^^^^^^^^
− test/golden/{numberCOLONd}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Decimal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- |-7 | main = putStrLn [fmt|{number:d}|]- | ^^^^^^^^^^^^
− test/golden/{numberCOLONo}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Octal) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- |-7 | main = putStrLn [fmt|{number:o}|]- | ^^^^^^^^^^^^
− test/golden/{numberCOLONx}.golden
@@ -1,9 +0,0 @@--INITIALPATH:7:22: error:- • No instance for (Integral Float) arising from a use of ‘PyF.Internal.QQ.formatAnyIntegral’- • In the first argument of ‘putStrLn’, namely ‘(((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)’- In the expression: putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- In an equation for ‘main’: main = putStrLn (((((PyF.Internal.QQ.formatAnyIntegral PyF.Formatters.Hexa) PyF.Formatters.Minus) (Nothing :: Maybe (Int, PyF.Formatters.AnyAlign, Char))) Nothing) number)- |-7 | main = putStrLn [fmt|{number:x}|]- | ^^^^^^^^^^^^
+ test/golden/{piCL.{SL}}.6840925804160914882.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:28: error:+ • parse error on input `/' in haskell expression+ • In the quasi-quotation: [fmt|{pi:.{/}}|]+ |+7 | main = putStrLn [fmt|{pi:.{/}}|]+ | ^
+ test/golden/{piCL.{}}.9894464503607709506.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:28: error:+ • +unexpected "}"+expecting an haskell expression+ • In the quasi-quotation: [fmt|{pi:.{}}|]+ |+7 | main = putStrLn [fmt|{pi:.{}}|]+ | ^
− test/golden/{piCOLON.{SLASH}}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:28:- |-7 | main = putStrLn [fmt|{pi:.{/}}|]- | ^-parse error on input `/' in haskell expression-- • In the quasi-quotation: [fmt|{pi:.{/}}|]- |-7 | main = putStrLn [fmt|{pi:.{/}}|]- | ^^^^^^^^^^^
− test/golden/{piCOLON.{}}.golden
@@ -1,14 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:28:- |-7 | main = putStrLn [fmt|{pi:.{}}|]- | ^--unexpected "}"-expecting an haskell expression-- • In the quasi-quotation: [fmt|{pi:.{}}|]- |-7 | main = putStrLn [fmt|{pi:.{}}|]- | ^^^^^^^^^^
+ test/golden/{truncate numberCL.3b}.11608798523190422838.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:41: error:+ • Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.+ • In the quasi-quotation: [fmt|{truncate number:.3b}|]+ |+7 | main = putStrLn [fmt|{truncate number:.3b}|]+ | ^
+ test/golden/{truncate numberCL.3d}.9142976352287206710.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:41: error:+ • Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.+ • In the quasi-quotation: [fmt|{truncate number:.3d}|]+ |+7 | main = putStrLn [fmt|{truncate number:.3d}|]+ | ^
+ test/golden/{truncate numberCL.3o}.1443712191031422262.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:41: error:+ • Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.+ • In the quasi-quotation: [fmt|{truncate number:.3o}|]+ |+7 | main = putStrLn [fmt|{truncate number:.3o}|]+ | ^
+ test/golden/{truncate numberCL.3x}.12613302271643495734.golden view
@@ -0,0 +1,7 @@++INITIALPATH:7:41: error:+ • Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.+ • In the quasi-quotation: [fmt|{truncate number:.3x}|]+ |+7 | main = putStrLn [fmt|{truncate number:.3x}|]+ | ^
− test/golden/{truncate numberCOLON.3b}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:41:- |-7 | main = putStrLn [fmt|{truncate number:.3b}|]- | ^-Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.-- • In the quasi-quotation: [fmt|{truncate number:.3b}|]- |-7 | main = putStrLn [fmt|{truncate number:.3b}|]- | ^^^^^^^^^^^^^^^^^^^^^^^
− test/golden/{truncate numberCOLON.3d}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:41:- |-7 | main = putStrLn [fmt|{truncate number:.3d}|]- | ^-Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.-- • In the quasi-quotation: [fmt|{truncate number:.3d}|]- |-7 | main = putStrLn [fmt|{truncate number:.3d}|]- | ^^^^^^^^^^^^^^^^^^^^^^^
− test/golden/{truncate numberCOLON.3o}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:41:- |-7 | main = putStrLn [fmt|{truncate number:.3o}|]- | ^-Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.-- • In the quasi-quotation: [fmt|{truncate number:.3o}|]- |-7 | main = putStrLn [fmt|{truncate number:.3o}|]- | ^^^^^^^^^^^^^^^^^^^^^^^
− test/golden/{truncate numberCOLON.3x}.golden
@@ -1,12 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:41:- |-7 | main = putStrLn [fmt|{truncate number:.3x}|]- | ^-Type incompatible with precision (.3), use any of {'e', 'E', 'f', 'F', 'g', 'G', 'n', 's', '%'} or remove the precision field.-- • In the quasi-quotation: [fmt|{truncate number:.3x}|]- |-7 | main = putStrLn [fmt|{truncate number:.3x}|]- | ^^^^^^^^^^^^^^^^^^^^^^^
+ test/golden/{}.14986928820806517861.golden view
@@ -0,0 +1,9 @@++INITIALPATH:7:23: error:+ • +unexpected "}"+expecting an haskell expression+ • In the quasi-quotation: [fmt|{}|]+ |+7 | main = putStrLn [fmt|{}|]+ | ^
− test/golden/{}.golden
@@ -1,14 +0,0 @@--INITIALPATH:7:22: error:- • INITIALPATH:7:23:- |-7 | main = putStrLn [fmt|{}|]- | ^--unexpected "}"-expecting an haskell expression-- • In the quasi-quotation: [fmt|{}|]- |-7 | main = putStrLn [fmt|{}|]- | ^^^^