{-# language CPP #-}
{-# language AllowAmbiguousTypes #-}

{-# options_ghc -fno-warn-name-shadowing #-}

module Nix.Pretty where

import           Nix.Prelude             hiding ( toList, group )
import           Control.Monad.Free             ( Free(Free) )
import           Data.Fix                       ( Fix(..)
                                                , foldFix )
import           Data.HashMap.Lazy              ( toList )
import qualified Data.HashMap.Lazy             as M
import qualified Data.HashSet                  as HashSet
import qualified Data.List.NonEmpty            as NE
import           Data.Text                      ( replace
                                                , strip
                                                )
import qualified Data.Text                     as Text
import           Prettyprinter           hiding ( list )
import           Nix.Atoms
import           Nix.Cited
import           Nix.Expr.Types
import           Nix.Expr.Types.Annotated
import           Nix.Expr.Strings
import           Nix.Normal
import           Nix.Parser
import           Nix.String
import           Nix.Thunk
import           Nix.Value

-- | This type represents a pretty printed nix expression
-- together with some information about the expression.
data NixDoc ann = NixDoc
  { -- | Rendered expression. Without surrounding parenthesis.
    forall ann. NixDoc ann -> Doc ann
getDoc :: Doc ann

    -- | The root operator is the operator at the root of
    -- the expression tree. For example, in '(a * b) + c', '+' would be the root
    -- operator. It is needed to determine if we need to wrap the expression in
    -- parentheses.
  , forall ann. NixDoc ann -> NOperatorDef
rootOp :: NOperatorDef
  , forall ann. NixDoc ann -> Bool
wasPath :: Bool -- This is needed so that when a path is used in a selector path
                    -- we can add brackets appropriately
  }

-- | Represent Nix antiquotes.
--
-- >
-- > ${ expr }
-- >
antiquote :: NixDoc ann -> Doc ann
antiquote :: forall ann. NixDoc ann -> Doc ann
antiquote NixDoc ann
x = Doc ann
"${" forall a. Semigroup a => a -> a -> a
<> forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
x forall a. Semigroup a => a -> a -> a
<> Doc ann
"}"

mkNixDoc :: NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc :: forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc NOperatorDef
o Doc ann
d = NixDoc { getDoc :: Doc ann
getDoc = Doc ann
d, rootOp :: NOperatorDef
rootOp = NOperatorDef
o, wasPath :: Bool
wasPath = Bool
False }

-- | A simple expression is never wrapped in parentheses. The expression
--   behaves as if its root operator had a precedence higher than all
--   other operators (including function application).
simpleExpr :: Doc ann -> NixDoc ann
simpleExpr :: forall ann. Doc ann -> NixDoc ann
simpleExpr =
  forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc forall a b. (a -> b) -> a -> b
$ NSpecialOp -> NAssoc -> NOpPrecedence -> NOpName -> NOperatorDef
NSpecialDef NSpecialOp
NTerm NAssoc
NAssoc forall a. Bounded a => a
minBound NOpName
"simple expr"

pathExpr :: Doc ann -> NixDoc ann
pathExpr :: forall ann. Doc ann -> NixDoc ann
pathExpr Doc ann
d = (forall ann. Doc ann -> NixDoc ann
simpleExpr Doc ann
d) { wasPath :: Bool
wasPath = Bool
True }

-- | An expression that behaves as if its root operator had a precedence lower
--   than all other operators. That ensures that the expression is wrapped in
--   parentheses in almost always, but it's still rendered without parentheses
--   in cases where parentheses are never required (such as in the LHS of a
--   binding).
leastPrecedence :: Doc ann -> NixDoc ann
leastPrecedence :: forall ann. Doc ann -> NixDoc ann
leastPrecedence =
  forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc forall a b. (a -> b) -> a -> b
$ NSpecialOp -> NAssoc -> NOpPrecedence -> NOpName -> NOperatorDef
NSpecialDef NSpecialOp
NTerm NAssoc
NAssoc forall a. Bounded a => a
maxBound NOpName
"least precedence"


data WrapMode
  = ProcessAllWrap
  | PrecedenceWrap
 deriving WrapMode -> WrapMode -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WrapMode -> WrapMode -> Bool
$c/= :: WrapMode -> WrapMode -> Bool
== :: WrapMode -> WrapMode -> Bool
$c== :: WrapMode -> WrapMode -> Bool
Eq

needsParens
  :: WrapMode
  -> NOperatorDef
  -> NOperatorDef
  -> Bool
needsParens :: WrapMode -> NOperatorDef -> NOperatorDef -> Bool
needsParens WrapMode
mode NOperatorDef
host NOperatorDef
sub =
  forall a. NOp a => a -> NOpPrecedence
getOpPrecedence NOperatorDef
host forall a. Ord a => a -> a -> Bool
> forall a. NOp a => a -> NOpPrecedence
getOpPrecedence NOperatorDef
sub
  Bool -> Bool -> Bool
|| forall a. a -> a -> Bool -> a
bool
    Bool
False
    ( NAssoc
NAssoc forall a. Eq a => a -> a -> Bool
/=  forall a. NOp a => a -> NAssoc
getOpAssoc      NOperatorDef
host
      Bool -> Bool -> Bool
&& forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on forall a. Eq a => a -> a -> Bool
(==) forall a. NOp a => a -> NAssoc
getOpAssoc      NOperatorDef
host NOperatorDef
sub
      Bool -> Bool -> Bool
&& forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on forall a. Eq a => a -> a -> Bool
(==) forall a. NOp a => a -> NOpPrecedence
getOpPrecedence NOperatorDef
host NOperatorDef
sub
    )
    (WrapMode
ProcessAllWrap forall a. Eq a => a -> a -> Bool
== WrapMode
mode)

maybeWrapDoc :: WrapMode -> NOperatorDef -> NixDoc ann -> Doc ann
maybeWrapDoc :: forall ann. WrapMode -> NOperatorDef -> NixDoc ann -> Doc ann
maybeWrapDoc WrapMode
mode NOperatorDef
host NixDoc ann
sub =
  forall a. a -> a -> Bool -> a
bool
    forall ann. Doc ann -> Doc ann
parens
    forall a. a -> a
id
    (WrapMode -> NOperatorDef -> NOperatorDef -> Bool
needsParens WrapMode
mode NOperatorDef
host (forall ann. NixDoc ann -> NOperatorDef
rootOp NixDoc ann
sub))
    (forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
sub)

-- | Determine if to return doc wraped into parens,
-- according the given operator.
wrap :: NOperatorDef -> NixDoc ann -> Doc ann
wrap :: forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrap = forall ann. WrapMode -> NOperatorDef -> NixDoc ann -> Doc ann
maybeWrapDoc WrapMode
ProcessAllWrap

precedenceWrap :: NOperatorDef -> NixDoc ann -> Doc ann
precedenceWrap :: forall ann. NOperatorDef -> NixDoc ann -> Doc ann
precedenceWrap = forall ann. WrapMode -> NOperatorDef -> NixDoc ann -> Doc ann
maybeWrapDoc WrapMode
PrecedenceWrap

-- Used in the selector case to print a path in a selector as
-- "${./abc}"
wrapPath :: NOperatorDef -> NixDoc ann -> Doc ann
wrapPath :: forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrapPath NOperatorDef
op NixDoc ann
sub =
  forall a. a -> a -> Bool -> a
bool
    (forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrap NOperatorDef
op NixDoc ann
sub)
    (forall ann. Doc ann -> Doc ann
dquotes forall a b. (a -> b) -> a -> b
$ forall ann. NixDoc ann -> Doc ann
antiquote NixDoc ann
sub)
    (forall ann. NixDoc ann -> Bool
wasPath NixDoc ann
sub)

-- | Handle Output representation of the string escape codes.
prettyString :: NString (NixDoc ann) -> Doc ann
prettyString :: forall ann. NString (NixDoc ann) -> Doc ann
prettyString (DoubleQuoted [Antiquoted Text (NixDoc ann)]
parts) =
  forall ann. Doc ann -> Doc ann
dquotes forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall {ann}. Antiquoted Text (NixDoc ann) -> Doc ann
prettyPart [Antiquoted Text (NixDoc ann)]
parts
 where
  prettyPart :: Antiquoted Text (NixDoc ann) -> Doc ann
prettyPart (Plain Text
t)      = forall a ann. Pretty a => a -> Doc ann
pretty forall a b. (a -> b) -> a -> b
$ Text -> Text
escapeString Text
t
  prettyPart Antiquoted Text (NixDoc ann)
EscapedNewline = Doc ann
"''\\n"
  prettyPart (Antiquoted NixDoc ann
r) = forall ann. NixDoc ann -> Doc ann
antiquote NixDoc ann
r
prettyString (Indented Int
_ [Antiquoted Text (NixDoc ann)]
parts) =
  forall ann. Doc ann -> Doc ann
group forall a b. (a -> b) -> a -> b
$ forall ann. Int -> Doc ann -> Doc ann
nest Int
2 forall a b. (a -> b) -> a -> b
$ forall ann. [Doc ann] -> Doc ann
vcat [Doc ann
"''", Doc ann
content, Doc ann
"''"]
 where
  content :: Doc ann
content = forall ann. [Doc ann] -> Doc ann
vsep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ann. [Antiquoted Text (NixDoc ann)] -> Doc ann
prettyLine forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. [[Antiquoted Text r]] -> [[Antiquoted Text r]]
stripLastIfEmpty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. [Antiquoted Text r] -> [[Antiquoted Text r]]
splitLines forall a b. (a -> b) -> a -> b
$ [Antiquoted Text (NixDoc ann)]
parts
  stripLastIfEmpty :: [[Antiquoted Text r]] -> [[Antiquoted Text r]]
  stripLastIfEmpty :: forall r. [[Antiquoted Text r]] -> [[Antiquoted Text r]]
stripLastIfEmpty =
    forall a. (a -> Bool) -> [a] -> [a]
filter forall r. [Antiquoted Text r] -> Bool
flt
   where
    flt :: [Antiquoted Text r] -> Bool
    flt :: forall r. [Antiquoted Text r] -> Bool
flt [Plain Text
t] | Text -> Bool
Text.null (Text -> Text
strip Text
t) = Bool
False
    flt [Antiquoted Text r]
_ = Bool
True

  prettyLine :: [Antiquoted Text (NixDoc ann)] -> Doc ann
  prettyLine :: forall ann. [Antiquoted Text (NixDoc ann)] -> Doc ann
prettyLine =
    forall ann. [Doc ann] -> Doc ann
hcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {ann}. Antiquoted Text (NixDoc ann) -> Doc ann
prettyPart
   where
    prettyPart :: Antiquoted Text (NixDoc ann) -> Doc ann
    prettyPart :: forall {ann}. Antiquoted Text (NixDoc ann) -> Doc ann
prettyPart (Plain Text
t) =
      forall a ann. Pretty a => a -> Doc ann
pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> Text -> Text
replace Text
"${" Text
"''${" forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> Text -> Text
replace Text
"''" Text
"'''" forall a b. (a -> b) -> a -> b
$ Text
t
    prettyPart Antiquoted Text (NixDoc ann)
EscapedNewline = Doc ann
"\\n"
    prettyPart (Antiquoted NixDoc ann
r) = forall ann. NixDoc ann -> Doc ann
antiquote NixDoc ann
r

prettyVarName :: VarName -> Doc ann
prettyVarName :: forall ann. VarName -> Doc ann
prettyVarName = forall a ann. Pretty a => a -> Doc ann
pretty @Text forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

prettyParams :: Params (NixDoc ann) -> Doc ann
prettyParams :: forall ann. Params (NixDoc ann) -> Doc ann
prettyParams (Param VarName
n           ) = forall ann. VarName -> Doc ann
prettyVarName VarName
n
prettyParams (ParamSet Maybe VarName
mname Variadic
variadic ParamSet (NixDoc ann)
pset) =
  forall ann. Variadic -> ParamSet (NixDoc ann) -> Doc ann
prettyParamSet Variadic
variadic ParamSet (NixDoc ann)
pset forall a. Semigroup a => a -> a -> a
<>
    forall ann. VarName -> Doc ann
toDoc forall b a. Monoid b => (a -> b) -> Maybe a -> b
`whenJust` Maybe VarName
mname
 where
  toDoc :: VarName -> Doc ann
  toDoc :: forall ann. VarName -> Doc ann
toDoc (coerce :: forall a b. Coercible a b => a -> b
coerce -> Text
name) =
    (Doc ann
"@" forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Text
name) forall a. Monoid a => a -> Bool -> a
`whenFalse` Text -> Bool
Text.null Text
name

prettyParamSet :: forall ann . Variadic -> ParamSet (NixDoc ann) -> Doc ann
prettyParamSet :: forall ann. Variadic -> ParamSet (NixDoc ann) -> Doc ann
prettyParamSet Variadic
variadic ParamSet (NixDoc ann)
args =
  forall ann. Doc ann -> Doc ann -> Doc ann -> [Doc ann] -> Doc ann
encloseSep
    Doc ann
"{ "
    (forall ann. Doc ann -> Doc ann
align Doc ann
" }")
    (forall ann. Doc ann -> Doc ann
align Doc ann
", ")
    (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (VarName, Maybe (NixDoc ann)) -> Doc ann
prettySetArg ParamSet (NixDoc ann)
args forall a. Semigroup a => a -> a -> a
<> forall x. One x => OneItem x -> x
one Doc ann
"..." forall a. Monoid a => a -> Bool -> a
`whenTrue` (Variadic
variadic forall a. Eq a => a -> a -> Bool
== Variadic
Variadic))
 where
  prettySetArg :: (VarName, Maybe (NixDoc ann)) -> Doc ann
  prettySetArg :: (VarName, Maybe (NixDoc ann)) -> Doc ann
prettySetArg (VarName
n, Maybe (NixDoc ann)
maybeDef) =
    (forall ann. VarName -> Doc ann
prettyVarName VarName
n forall a. Semigroup a => a -> a -> a
<>) forall a b. (a -> b) -> a -> b
$ ((Doc ann
" ? " forall a. Semigroup a => a -> a -> a
<>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann. NixDoc ann -> Doc ann
getDoc) forall b a. Monoid b => (a -> b) -> Maybe a -> b
`whenJust` Maybe (NixDoc ann)
maybeDef

prettyBind :: Binding (NixDoc ann) -> Doc ann
prettyBind :: forall ann. Binding (NixDoc ann) -> Doc ann
prettyBind (NamedVar NAttrPath (NixDoc ann)
n NixDoc ann
v NSourcePos
_p) =
  forall ann. NAttrPath (NixDoc ann) -> Doc ann
prettySelector NAttrPath (NixDoc ann)
n forall a. Semigroup a => a -> a -> a
<> Doc ann
" = " forall a. Semigroup a => a -> a -> a
<> forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
v forall a. Semigroup a => a -> a -> a
<> Doc ann
";"
prettyBind (Inherit Maybe (NixDoc ann)
s [VarName]
ns NSourcePos
_p) =
  Doc ann
"inherit " forall a. Semigroup a => a -> a -> a
<> Doc ann
scope forall a. Semigroup a => a -> a -> a
<> forall ann. Doc ann -> Doc ann
align (forall ann. [Doc ann] -> Doc ann
fillSep forall a b. (a -> b) -> a -> b
$ forall ann. VarName -> Doc ann
prettyVarName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [VarName]
ns) forall a. Semigroup a => a -> a -> a
<> Doc ann
";"
 where
  scope :: Doc ann
scope =
    ((forall a. Semigroup a => a -> a -> a
<> Doc ann
" ") forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann. Doc ann -> Doc ann
parens forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann. NixDoc ann -> Doc ann
getDoc) forall b a. Monoid b => (a -> b) -> Maybe a -> b
`whenJust` Maybe (NixDoc ann)
s

prettyKeyName :: NKeyName (NixDoc ann) -> Doc ann
prettyKeyName :: forall ann. NKeyName (NixDoc ann) -> Doc ann
prettyKeyName (StaticKey VarName
key) =
  forall a. a -> a -> Bool -> a
bool
    Doc ann
"\"\""
    (forall a. a -> a -> Bool -> a
bool
      forall a. a -> a
id
      forall ann. Doc ann -> Doc ann
dquotes
      (forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
HashSet.member VarName
key HashSet VarName
reservedNames)
      (forall ann. VarName -> Doc ann
prettyVarName VarName
key)
    )
    (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Text -> Bool
Text.null forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce VarName
key)
prettyKeyName (DynamicKey Antiquoted (NString (NixDoc ann)) (NixDoc ann)
key) =
  forall v a r. v -> (v -> a) -> (r -> a) -> Antiquoted v r -> a
runAntiquoted
    (forall r. [Antiquoted Text r] -> NString r
DoubleQuoted forall a b. (a -> b) -> a -> b
$ forall x. One x => OneItem x -> x
one forall a b. (a -> b) -> a -> b
$ forall v r. v -> Antiquoted v r
Plain Text
"\n")
    forall ann. NString (NixDoc ann) -> Doc ann
prettyString
    forall ann. NixDoc ann -> Doc ann
antiquote
    Antiquoted (NString (NixDoc ann)) (NixDoc ann)
key

prettySelector :: NAttrPath (NixDoc ann) -> Doc ann
prettySelector :: forall ann. NAttrPath (NixDoc ann) -> Doc ann
prettySelector = forall ann. [Doc ann] -> Doc ann
hcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc ann
"." forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ann. NKeyName (NixDoc ann) -> Doc ann
prettyKeyName forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> [a]
NE.toList

prettyAtom :: NAtom -> NixDoc ann
prettyAtom :: forall ann. NAtom -> NixDoc ann
prettyAtom = forall ann. Doc ann -> NixDoc ann
simpleExpr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a ann. Pretty a => a -> Doc ann
pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. NAtom -> Text
atomText

prettyNix :: NExpr -> Doc ann
prettyNix :: forall ann. NExpr -> Doc ann
prettyNix = forall ann. NixDoc ann -> Doc ann
getDoc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
foldFix forall ann. NExprF (NixDoc ann) -> NixDoc ann
exprFNixDoc

prettyOriginExpr
  :: forall t f m ann
   . HasCitations1 m (NValue t f m) f
  => NExprLocF (Maybe (NValue t f m))
  -> Doc ann
prettyOriginExpr :: forall t (f :: * -> *) (m :: * -> *) ann.
HasCitations1 m (NValue t f m) f =>
NExprLocF (Maybe (NValue t f m)) -> Doc ann
prettyOriginExpr = forall ann. NixDoc ann -> Doc ann
getDoc forall b c a. (b -> c) -> (a -> b) -> a -> c
. NExprLocF (Maybe (NValue t f m)) -> NixDoc ann
go
 where
  go :: NExprLocF (Maybe (NValue t f m)) -> NixDoc ann
  go :: NExprLocF (Maybe (NValue t f m)) -> NixDoc ann
go = forall ann. NExprF (NixDoc ann) -> NixDoc ann
exprFNixDoc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann (f :: * -> *) r. AnnF ann f r -> f r
stripAnnF forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe (NValue t f m) -> NixDoc ann
render
   where
    render :: Maybe (NValue t f m) -> NixDoc ann
    render :: Maybe (NValue t f m) -> NixDoc ann
render Maybe (NValue t f m)
Nothing = forall ann. Doc ann -> NixDoc ann
simpleExpr Doc ann
"_"
    render (Just (Free (forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) v a.
HasCitations m v a =>
a -> [Provenance m v]
citations @m -> Provenance m (NValue t f m)
p:[Provenance m (NValue t f m)]
_))) = NExprLocF (Maybe (NValue t f m)) -> NixDoc ann
go (forall (m :: * -> *) v. Provenance m v -> NExprLocF (Maybe v)
getOriginExpr Provenance m (NValue t f m)
p)
    render Maybe (NValue t f m)
_       = forall ann. Doc ann -> NixDoc ann
simpleExpr Doc ann
"?"
      -- render (Just (NValue (citations -> ps))) =
          -- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . getDoc
          --                           . go . originExpr)
          --     mempty (reverse ps)

-- | Takes original expression from inside provenance information.
-- Prettifies that expression.
prettyExtractFromProvenance
  :: forall t f m ann
   . HasCitations1 m (NValue t f m) f
  => [Provenance m (NValue t f m)] -> Doc ann
prettyExtractFromProvenance :: forall t (f :: * -> *) (m :: * -> *) ann.
HasCitations1 m (NValue t f m) f =>
[Provenance m (NValue t f m)] -> Doc ann
prettyExtractFromProvenance =
  forall ann. [Doc ann] -> Doc ann
sep forall b c a. (b -> c) -> (a -> b) -> a -> c
.
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall t (f :: * -> *) (m :: * -> *) ann.
HasCitations1 m (NValue t f m) f =>
NExprLocF (Maybe (NValue t f m)) -> Doc ann
prettyOriginExpr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) v. Provenance m v -> NExprLocF (Maybe v)
getOriginExpr)

exprFNixDoc :: forall ann . NExprF (NixDoc ann) -> NixDoc ann
exprFNixDoc :: forall ann. NExprF (NixDoc ann) -> NixDoc ann
exprFNixDoc = \case
  NConstant NAtom
atom -> forall ann. NAtom -> NixDoc ann
prettyAtom NAtom
atom
  NStr      NString (NixDoc ann)
str  -> forall ann. Doc ann -> NixDoc ann
simpleExpr forall a b. (a -> b) -> a -> b
$ forall ann. NString (NixDoc ann) -> Doc ann
prettyString NString (NixDoc ann)
str
  NList [NixDoc ann]
xs ->
    forall {ann} {a}.
Doc ann -> (a -> Doc ann) -> Doc ann -> [a] -> NixDoc ann
prettyContainer Doc ann
"[" (forall ann. NOperatorDef -> NixDoc ann -> Doc ann
precedenceWrap NOperatorDef
appOpDef) Doc ann
"]" [NixDoc ann]
xs
  NSet Recursivity
NonRecursive [Binding (NixDoc ann)]
xs ->
    forall {ann} {a}.
Doc ann -> (a -> Doc ann) -> Doc ann -> [a] -> NixDoc ann
prettyContainer Doc ann
"{" forall ann. Binding (NixDoc ann) -> Doc ann
prettyBind Doc ann
"}" [Binding (NixDoc ann)]
xs
  NSet Recursivity
Recursive [Binding (NixDoc ann)]
xs ->
    forall {ann} {a}.
Doc ann -> (a -> Doc ann) -> Doc ann -> [a] -> NixDoc ann
prettyContainer Doc ann
"rec {" forall ann. Binding (NixDoc ann) -> Doc ann
prettyBind Doc ann
"}" [Binding (NixDoc ann)]
xs
  NAbs Params (NixDoc ann)
args NixDoc ann
body ->
    forall ann. Doc ann -> NixDoc ann
leastPrecedence forall a b. (a -> b) -> a -> b
$
      forall ann. Int -> Doc ann -> Doc ann
nest Int
2 forall a b. (a -> b) -> a -> b
$
        forall ann. [Doc ann] -> Doc ann
vsep
          [ forall ann. Params (NixDoc ann) -> Doc ann
prettyParams Params (NixDoc ann)
args forall a. Semigroup a => a -> a -> a
<> Doc ann
":"
          , forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
body
          ]
  NApp NixDoc ann
fun NixDoc ann
arg ->
    forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc NOperatorDef
appOpDef (forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrap NOperatorDef
appOpDef NixDoc ann
fun forall a. Semigroup a => a -> a -> a
<> Doc ann
" " forall a. Semigroup a => a -> a -> a
<> forall ann. NOperatorDef -> NixDoc ann -> Doc ann
precedenceWrap NOperatorDef
appOpDef NixDoc ann
arg)
  NBinary NBinaryOp
op NixDoc ann
r1 NixDoc ann
r2 ->
    forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc
      NOperatorDef
opDef forall a b. (a -> b) -> a -> b
$
      forall ann. [Doc ann] -> Doc ann
hsep
        [ NAssoc -> NixDoc ann -> Doc ann
pickWrapMode NAssoc
NAssocLeft NixDoc ann
r1
        , forall a ann. Pretty a => a -> Doc ann
pretty @Text forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce @NOpName forall a b. (a -> b) -> a -> b
$ forall a. NOp a => a -> NOpName
getOpName NBinaryOp
op
        , NAssoc -> NixDoc ann -> Doc ann
pickWrapMode NAssoc
NAssocRight NixDoc ann
r2
        ]
   where
    opDef :: NOperatorDef
opDef = forall a. NOp a => a -> NOperatorDef
getOpDef NBinaryOp
op

    pickWrapMode :: NAssoc -> NixDoc ann -> Doc ann
    pickWrapMode :: NAssoc -> NixDoc ann -> Doc ann
pickWrapMode NAssoc
x =
      forall a. a -> a -> Bool -> a
bool
        forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrap
        forall ann. NOperatorDef -> NixDoc ann -> Doc ann
precedenceWrap
        (forall a. NOp a => a -> NAssoc
getOpAssoc NOperatorDef
opDef forall a. Eq a => a -> a -> Bool
/= NAssoc
x)
        NOperatorDef
opDef
  NUnary NUnaryOp
op NixDoc ann
r1 ->
    forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc
      NOperatorDef
opDef forall a b. (a -> b) -> a -> b
$
      forall a ann. Pretty a => a -> Doc ann
pretty @Text (coerce :: forall a b. Coercible a b => a -> b
coerce forall a b. (a -> b) -> a -> b
$ forall a. NOp a => a -> NOpName
getOpName NUnaryOp
op) forall a. Semigroup a => a -> a -> a
<> forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrap NOperatorDef
opDef NixDoc ann
r1
   where
    opDef :: NOperatorDef
opDef = forall a. NOp a => a -> NOperatorDef
getOpDef NUnaryOp
op
  NSelect Maybe (NixDoc ann)
o NixDoc ann
r' NAttrPath (NixDoc ann)
attr ->
    forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc NOperatorDef
selectOp)
      (forall a b. a -> b -> a
const forall ann. Doc ann -> NixDoc ann
leastPrecedence)
      Maybe (NixDoc ann)
o
      forall a b. (a -> b) -> a -> b
$ forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrapPath NOperatorDef
selectOp (forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc NOperatorDef
selectOp (forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrap NOperatorDef
appOpDef NixDoc ann
r')) forall a. Semigroup a => a -> a -> a
<> Doc ann
"." forall a. Semigroup a => a -> a -> a
<> forall ann. NAttrPath (NixDoc ann) -> Doc ann
prettySelector NAttrPath (NixDoc ann)
attr forall a. Semigroup a => a -> a -> a
<>
        ((Doc ann
" or " forall a. Semigroup a => a -> a -> a
<>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall ann. NOperatorDef -> NixDoc ann -> Doc ann
precedenceWrap NOperatorDef
appOpDef) forall b a. Monoid b => (a -> b) -> Maybe a -> b
`whenJust` Maybe (NixDoc ann)
o
   where
    selectOp :: NOperatorDef
    selectOp :: NOperatorDef
selectOp = forall a. NOp a => a -> NOperatorDef
getOpDef NSpecialOp
NSelectOp

  NHasAttr NixDoc ann
r NAttrPath (NixDoc ann)
attr ->
    forall ann. NOperatorDef -> Doc ann -> NixDoc ann
mkNixDoc NOperatorDef
hasAttrOp (forall ann. NOperatorDef -> NixDoc ann -> Doc ann
wrap NOperatorDef
hasAttrOp NixDoc ann
r forall a. Semigroup a => a -> a -> a
<> Doc ann
" ? " forall a. Semigroup a => a -> a -> a
<> forall ann. NAttrPath (NixDoc ann) -> Doc ann
prettySelector NAttrPath (NixDoc ann)
attr)
   where
    hasAttrOp :: NOperatorDef
    hasAttrOp :: NOperatorDef
hasAttrOp = forall a. NOp a => a -> NOperatorDef
getOpDef NSpecialOp
NHasAttrOp

  NEnvPath     Path
p -> forall ann. Doc ann -> NixDoc ann
simpleExpr forall a b. (a -> b) -> a -> b
$ forall a ann. Pretty a => a -> Doc ann
pretty @String forall a b. (a -> b) -> a -> b
$ String
"<" forall a. Semigroup a => a -> a -> a
<> coerce :: forall a b. Coercible a b => a -> b
coerce Path
p forall a. Semigroup a => a -> a -> a
<> String
">"
  NLiteralPath Path
p ->
    forall ann. Doc ann -> NixDoc ann
pathExpr forall a b. (a -> b) -> a -> b
$
      forall a ann. Pretty a => a -> Doc ann
pretty @FilePath forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce forall a b. (a -> b) -> a -> b
$
        case Path
p of
          Path
"./"  -> Path
"./."
          Path
"../" -> Path
"../."
          Path
".."  -> Path
"../."
          Path
path  ->
            forall a. a -> a -> Bool -> a
bool
              (Path
"./" forall a. Semigroup a => a -> a -> a
<> Path
path)
              Path
path
              (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` coerce :: forall a b. Coercible a b => a -> b
coerce Path
path) [String
"/", String
"~/", String
"./", String
"../"])
  NSym VarName
name -> forall ann. Doc ann -> NixDoc ann
simpleExpr forall a b. (a -> b) -> a -> b
$ forall ann. VarName -> Doc ann
prettyVarName VarName
name
  NLet [Binding (NixDoc ann)]
binds NixDoc ann
body ->
    forall ann. Doc ann -> NixDoc ann
leastPrecedence forall a b. (a -> b) -> a -> b
$
      forall ann. Doc ann -> Doc ann
group forall a b. (a -> b) -> a -> b
$
        forall ann. [Doc ann] -> Doc ann
vsep
          [ Doc ann
"let"
          , forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (forall ann. [Doc ann] -> Doc ann
vsep forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall ann. Binding (NixDoc ann) -> Doc ann
prettyBind [Binding (NixDoc ann)]
binds)
          , Doc ann
"in " forall a. Semigroup a => a -> a -> a
<> forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
body
          ]
  NIf NixDoc ann
cond NixDoc ann
trueBody NixDoc ann
falseBody ->
    forall ann. Doc ann -> NixDoc ann
leastPrecedence forall a b. (a -> b) -> a -> b
$
      forall ann. Doc ann -> Doc ann
group forall a b. (a -> b) -> a -> b
$
        forall ann. Int -> Doc ann -> Doc ann
nest Int
2 Doc ann
ifThenElse
   where
    ifThenElse :: Doc ann
    ifThenElse :: Doc ann
ifThenElse =
      forall ann. [Doc ann] -> Doc ann
sep
        [         Doc ann
"if "   forall a. Semigroup a => a -> a -> a
<> forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
cond
        , forall ann. Doc ann -> Doc ann
align forall a b. (a -> b) -> a -> b
$ Doc ann
"then " forall a. Semigroup a => a -> a -> a
<> forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
trueBody
        , forall ann. Doc ann -> Doc ann
align forall a b. (a -> b) -> a -> b
$ Doc ann
"else " forall a. Semigroup a => a -> a -> a
<> forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
falseBody
        ]
  NWith NixDoc ann
scope NixDoc ann
body ->
    forall {ann}. Doc ann -> NixDoc ann -> NixDoc ann -> NixDoc ann
prettyAddScope Doc ann
"with " NixDoc ann
scope NixDoc ann
body
  NAssert NixDoc ann
cond NixDoc ann
body ->
    forall {ann}. Doc ann -> NixDoc ann -> NixDoc ann -> NixDoc ann
prettyAddScope Doc ann
"assert " NixDoc ann
cond NixDoc ann
body
  NSynHole VarName
name -> forall ann. Doc ann -> NixDoc ann
simpleExpr forall a b. (a -> b) -> a -> b
$ forall a ann. Pretty a => a -> Doc ann
pretty @Text (Text
"^" forall a. Semigroup a => a -> a -> a
<> coerce :: forall a b. Coercible a b => a -> b
coerce VarName
name)
 where
  prettyContainer :: Doc ann -> (a -> Doc ann) -> Doc ann -> [a] -> NixDoc ann
prettyContainer Doc ann
h a -> Doc ann
f Doc ann
t [a]
c =
    forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
handlePresence
      (forall ann. Doc ann -> NixDoc ann
simpleExpr (Doc ann
h forall a. Semigroup a => a -> a -> a
<> Doc ann
t))
      (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall ann. Doc ann -> NixDoc ann
simpleExpr forall a b. (a -> b) -> a -> b
$ forall ann. Doc ann -> Doc ann
group forall a b. (a -> b) -> a -> b
$ forall ann. Int -> Doc ann -> Doc ann
nest Int
2 (Doc ann
h forall a. Semigroup a => a -> a -> a
<> forall ann. Doc ann
line forall a. Semigroup a => a -> a -> a
<> forall ann. [Doc ann] -> Doc ann
vsep (a -> Doc ann
f forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a]
c)) forall a. Semigroup a => a -> a -> a
<> forall ann. Doc ann
line forall a. Semigroup a => a -> a -> a
<> Doc ann
t)
      [a]
c

  prettyAddScope :: Doc ann -> NixDoc ann -> NixDoc ann -> NixDoc ann
prettyAddScope Doc ann
h NixDoc ann
c NixDoc ann
b =
    forall ann. Doc ann -> NixDoc ann
leastPrecedence forall a b. (a -> b) -> a -> b
$
      forall ann. [Doc ann] -> Doc ann
vsep
        [Doc ann
h forall a. Semigroup a => a -> a -> a
<> forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
c forall a. Semigroup a => a -> a -> a
<> Doc ann
";", forall ann. Doc ann -> Doc ann
align forall a b. (a -> b) -> a -> b
$ forall ann. NixDoc ann -> Doc ann
getDoc NixDoc ann
b]


valueToExpr :: forall t f m . MonadDataContext f m => NValue t f m -> NExpr
valueToExpr :: forall t (f :: * -> *) (m :: * -> *).
MonadDataContext f m =>
NValue t f m -> NExpr
valueToExpr = forall (f :: * -> *) (m :: * -> *) r t.
MonadDataContext f m =>
r -> (NValue' t f m r -> r) -> NValue t f m -> r
iterNValueByDiscardWith NExpr
thk (forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. NValue' t f m NExpr -> NExprF NExpr
phi)
 where
  thk :: NExpr
thk = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. VarName -> NExprF r
NSym forall a b. (a -> b) -> a -> b
$ VarName
"<expr>"

  phi :: NValue' t f m NExpr -> NExprF NExpr
  phi :: NValue' t f m NExpr -> NExprF NExpr
phi (NVConstant' NAtom
a     ) = forall r. NAtom -> NExprF r
NConstant NAtom
a
  phi (NVStr'      NixString
ns    ) = forall r. NString r -> NExprF r
NStr forall a b. (a -> b) -> a -> b
$ forall r. [Antiquoted Text r] -> NString r
DoubleQuoted forall a b. (a -> b) -> a -> b
$ forall x. One x => OneItem x -> x
one forall a b. (a -> b) -> a -> b
$ forall v r. v -> Antiquoted v r
Plain forall a b. (a -> b) -> a -> b
$ NixString -> Text
ignoreContext NixString
ns
  phi (NVList'     [NExpr]
l     ) = forall r. [r] -> NExprF r
NList [NExpr]
l
  phi (NVSet'      PositionSet
p    AttrSet NExpr
s) = forall r. Recursivity -> [Binding r] -> NExprF r
NSet forall a. Monoid a => a
mempty
    [ forall r. NAttrPath r -> r -> NSourcePos -> Binding r
NamedVar (forall x. One x => OneItem x -> x
one forall a b. (a -> b) -> a -> b
$ forall r. VarName -> NKeyName r
StaticKey VarName
k) NExpr
v (forall a. a -> Maybe a -> a
fromMaybe NSourcePos
nullPos forall a b. (a -> b) -> a -> b
$ (forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
`M.lookup` PositionSet
p) VarName
k)
    | (VarName
k, NExpr
v) <- forall k v. HashMap k v -> [(k, v)]
toList AttrSet NExpr
s
    ]
  phi (NVClosure'  Params ()
_    NValue t f m -> m NExpr
_) = forall r. VarName -> NExprF r
NSym VarName
"<closure>"
  phi (NVPath'     Path
p     ) = forall r. Path -> NExprF r
NLiteralPath Path
p
  phi (NVBuiltin'  VarName
name NValue t f m -> m NExpr
_) = forall r. VarName -> NExprF r
NSym forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce ((forall a. Monoid a => a -> a -> a
mappend @Text) Text
"builtins.") VarName
name

prettyNValue
  :: forall t f m ann . MonadDataContext f m => NValue t f m -> Doc ann
prettyNValue :: forall t (f :: * -> *) (m :: * -> *) ann.
MonadDataContext f m =>
NValue t f m -> Doc ann
prettyNValue = forall ann. NExpr -> Doc ann
prettyNix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t (f :: * -> *) (m :: * -> *).
MonadDataContext f m =>
NValue t f m -> NExpr
valueToExpr

-- | During the output, which can print only representation of value,
-- lazy thunks need to looked into & so - be evaluated (*sic)
-- This type is a simple manual witness "is the thunk gets shown".
data ValueOrigin = WasThunk | Value
 deriving ValueOrigin -> ValueOrigin -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ValueOrigin -> ValueOrigin -> Bool
$c/= :: ValueOrigin -> ValueOrigin -> Bool
== :: ValueOrigin -> ValueOrigin -> Bool
$c== :: ValueOrigin -> ValueOrigin -> Bool
Eq

prettyProv
  :: forall t f m ann
   . ( HasCitations m (NValue t f m) t
     , HasCitations1 m (NValue t f m) f
     , MonadThunk t m (NValue t f m)
     , MonadDataContext f m
     )
  => ValueOrigin  -- ^ Was thunk?
  -> NValue t f m
  -> Doc ann
prettyProv :: forall t (f :: * -> *) (m :: * -> *) ann.
(HasCitations m (NValue t f m) t, HasCitations1 m (NValue t f m) f,
 MonadThunk t m (NValue t f m), MonadDataContext f m) =>
ValueOrigin -> NValue t f m -> Doc ann
prettyProv ValueOrigin
wasThunk NValue t f m
v =
  forall (t :: * -> *) b a. Foldable t => b -> (t a -> b) -> t a -> b
handlePresence
    forall a. a -> a
id
    (\ [Provenance m (NValue t f m)]
ps Doc ann
pv ->
      forall ann. [Doc ann] -> Doc ann
fillSep
        [ Doc ann
pv
        , forall ann. Int -> Doc ann -> Doc ann
indent Int
2 forall a b. (a -> b) -> a -> b
$
          Doc ann
"(" forall a. Semigroup a => a -> a -> a
<> (Doc ann
"thunk " forall a. Monoid a => a -> Bool -> a
`whenTrue` (ValueOrigin
wasThunk forall a. Eq a => a -> a -> Bool
== ValueOrigin
WasThunk) forall a. Semigroup a => a -> a -> a
<> Doc ann
"from: " forall a. Semigroup a => a -> a -> a
<> forall t (f :: * -> *) (m :: * -> *) ann.
HasCitations1 m (NValue t f m) f =>
[Provenance m (NValue t f m)] -> Doc ann
prettyExtractFromProvenance [Provenance m (NValue t f m)]
ps) forall a. Semigroup a => a -> a -> a
<> Doc ann
")"
        ]
    )
    (forall (m :: * -> *) v a.
HasCitations m v a =>
a -> [Provenance m v]
citations @m @(NValue t f m) NValue t f m
v)
    (forall t (f :: * -> *) (m :: * -> *) ann.
MonadDataContext f m =>
NValue t f m -> Doc ann
prettyNValue NValue t f m
v)

prettyNValueProv
  :: forall t f m ann
   . ( HasCitations m (NValue t f m) t
     , HasCitations1 m (NValue t f m) f
     , MonadThunk t m (NValue t f m)
     , MonadDataContext f m
     )
  => NValue t f m
  -> Doc ann
prettyNValueProv :: forall t (f :: * -> *) (m :: * -> *) ann.
(HasCitations m (NValue t f m) t, HasCitations1 m (NValue t f m) f,
 MonadThunk t m (NValue t f m), MonadDataContext f m) =>
NValue t f m -> Doc ann
prettyNValueProv =
  forall t (f :: * -> *) (m :: * -> *) ann.
(HasCitations m (NValue t f m) t, HasCitations1 m (NValue t f m) f,
 MonadThunk t m (NValue t f m), MonadDataContext f m) =>
ValueOrigin -> NValue t f m -> Doc ann
prettyProv ValueOrigin
Value

prettyNThunk
  :: forall t f m ann
   . ( HasCitations m (NValue t f m) t
     , HasCitations1 m (NValue t f m) f
     , MonadThunk t m (NValue t f m)
     , MonadDataContext f m
     )
  => t
  -> m (Doc ann)
prettyNThunk :: forall t (f :: * -> *) (m :: * -> *) ann.
(HasCitations m (NValue t f m) t, HasCitations1 m (NValue t f m) f,
 MonadThunk t m (NValue t f m), MonadDataContext f m) =>
t -> m (Doc ann)
prettyNThunk t
t =
  forall t (f :: * -> *) (m :: * -> *) ann.
(HasCitations m (NValue t f m) t, HasCitations1 m (NValue t f m) f,
 MonadThunk t m (NValue t f m), MonadDataContext f m) =>
ValueOrigin -> NValue t f m -> Doc ann
prettyProv ValueOrigin
WasThunk forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall t (m :: * -> *) (f :: * -> *).
(MonadThunk t m (NValue t f m), MonadDataContext f m) =>
t -> m (NValue t f m)
dethunk t
t

-- | This function is used only by the testing code.
printNix :: forall t f m . MonadDataContext f m => NValue t f m -> Text
printNix :: forall t (f :: * -> *) (m :: * -> *).
MonadDataContext f m =>
NValue t f m -> Text
printNix =
  forall (f :: * -> *) (m :: * -> *) r t.
MonadDataContext f m =>
r -> (NValue' t f m r -> r) -> NValue t f m -> r
iterNValueByDiscardWith Text
thunkStubText NValue' t f m Text -> Text
phi
 where
  phi :: NValue' t f m Text -> Text
  phi :: NValue' t f m Text -> Text
phi (NVConstant' NAtom
a ) = NAtom -> Text
atomText NAtom
a
  phi (NVStr'      NixString
ns) = Text
"\"" forall a. Semigroup a => a -> a -> a
<> Text -> Text
escapeString (NixString -> Text
ignoreContext NixString
ns) forall a. Semigroup a => a -> a -> a
<> Text
"\""
  phi (NVList'     [Text]
l ) = Text
"[ " forall a. Semigroup a => a -> a -> a
<> forall t. IsText t "unwords" => [t] -> t
unwords [Text]
l forall a. Semigroup a => a -> a -> a
<> Text
" ]"
  phi (NVSet' PositionSet
_ AttrSet Text
s) =
    Text
"{ " forall a. Semigroup a => a -> a -> a
<>
      forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
        [ Text -> Text
check Text
k forall a. Semigroup a => a -> a -> a
<> Text
" = " forall a. Semigroup a => a -> a -> a
<> Text
v forall a. Semigroup a => a -> a -> a
<> Text
"; "
        | (coerce :: forall a b. Coercible a b => a -> b
coerce -> Text
k, Text
v) <- forall a. Ord a => [a] -> [a]
sort forall a b. (a -> b) -> a -> b
$ forall k v. HashMap k v -> [(k, v)]
toList AttrSet Text
s
        ] forall a. Semigroup a => a -> a -> a
<> Text
"}"
   where
    check :: Text -> Text
    check :: Text -> Text
check Text
v =
      forall a. a -> Maybe a -> a
fromMaybe
        Text
v
        (forall a. (Read a, Show a) => Maybe Text
tryRead @Int forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. (Read a, Show a) => Maybe Text
tryRead @Float)
     where
      tryRead :: forall a . (Read a, Show a) => Maybe Text
      tryRead :: forall a. (Read a, Show a) => Maybe Text
tryRead = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((\ Text
s -> Text
"\"" forall a. Semigroup a => a -> a -> a
<> Text
s forall a. Semigroup a => a -> a -> a
<> Text
"\"") forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. (Show a, IsString b) => a -> b
show) forall a b. (a -> b) -> a -> b
$ forall a. Read a => String -> Maybe a
readMaybe @a forall a b. (a -> b) -> a -> b
$ forall a. ToString a => a -> String
toString Text
v
  phi NVClosure'{}        = Text
"<<lambda>>"
  phi (NVPath' Path
fp       ) = forall a. IsString a => String -> a
fromString forall a b. (a -> b) -> a -> b
$ coerce :: forall a b. Coercible a b => a -> b
coerce Path
fp
  phi (NVBuiltin' VarName
name NValue t f m -> m Text
_) = Text
"<<builtin " forall a. Semigroup a => a -> a -> a
<> coerce :: forall a b. Coercible a b => a -> b
coerce VarName
name forall a. Semigroup a => a -> a -> a
<> Text
">>"