-- | Shorthands for making Nix expressions.
--
-- Functions with an @F@ suffix return a more general type (base functor @F a@) without the outer
-- 'Fix' wrapper that creates @a@.
module Nix.Expr.Shorthands where

import           Nix.Prelude
import           Data.Fix
import           Nix.Atoms
import           Nix.Expr.Types

-- * Basic expression builders

-- | Put @NAtom@ as expression
mkConst :: NAtom -> NExpr
mkConst :: NAtom -> NExpr
mkConst = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. NAtom -> NExprF r
NConstant

-- | Put null.
mkNull :: NExpr
mkNull :: NExpr
mkNull = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall a. NExprF a
mkNullF

-- | Put boolean.
mkBool :: Bool -> NExpr
mkBool :: Bool -> NExpr
mkBool = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Bool -> NExprF a
mkBoolF

-- | Put integer.
mkInt :: Integer -> NExpr
mkInt :: Integer -> NExpr
mkInt = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Integer -> NExprF a
mkIntF

-- | Put floating point number.
mkFloat :: Float -> NExpr
mkFloat :: Float -> NExpr
mkFloat = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Float -> NExprF a
mkFloatF

-- | Put a regular (double-quoted) string.
mkStr :: Text -> NExpr
mkStr :: Text -> NExpr
mkStr = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. NString r -> NExprF r
NStr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. [Antiquoted Text r] -> NString r
DoubleQuoted forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall a. a -> (Text -> a) -> Text -> a
whenText
    forall a. Monoid a => a
mempty
    (forall x. One x => OneItem x -> x
one forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v r. v -> Antiquoted v r
Plain)

-- | Put an indented string.
mkIndentedStr :: Int -> Text -> NExpr
mkIndentedStr :: Int -> Text -> NExpr
mkIndentedStr Int
w = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. NString r -> NExprF r
NStr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. Int -> [Antiquoted Text r] -> NString r
Indented Int
w forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  forall a. a -> (Text -> a) -> Text -> a
whenText
    forall a. Monoid a => a
mempty
    (forall x. One x => OneItem x -> x
one forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v r. v -> Antiquoted v r
Plain)

-- | Put a path. Use @True@ if the path should be read from the environment, else use @False@.
mkPath :: Bool -> FilePath -> NExpr
mkPath :: Bool -> FilePath -> NExpr
mkPath Bool
b = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Bool -> FilePath -> NExprF a
mkPathF Bool
b

-- | Put a path expression which pulls from the @NIX_PATH@ @env@ variable.
mkEnvPath :: FilePath -> NExpr
mkEnvPath :: FilePath -> NExpr
mkEnvPath = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FilePath -> NExprF a
mkEnvPathF

-- | Put a path which references a relative path.
mkRelPath :: FilePath -> NExpr
mkRelPath :: FilePath -> NExpr
mkRelPath = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FilePath -> NExprF a
mkRelPathF

-- | Put a variable (symbol).
mkSym :: Text -> NExpr
mkSym :: Text -> NExpr
mkSym = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Text -> NExprF a
mkSymF

-- | Put syntactic hole.
mkSynHole :: Text -> NExpr
mkSynHole :: Text -> NExpr
mkSynHole = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Text -> NExprF a
mkSynHoleF

mkSelector :: Text -> NAttrPath NExpr
mkSelector :: Text -> NAttrPath NExpr
mkSelector = forall x. One x => OneItem x -> x
one forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. VarName -> NKeyName r
StaticKey forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

-- | Put a binary operator.
--  @since
mkApp :: NExpr -> NExpr -> NExpr
mkApp :: NExpr -> NExpr -> NExpr
mkApp NExpr
a = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. r -> r -> NExprF r
NApp NExpr
a
-- | Put an unary operator.

--  @since 0.15.0
mkOp :: NUnaryOp -> NExpr -> NExpr
mkOp :: NUnaryOp -> NExpr -> NExpr
mkOp NUnaryOp
op = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. NUnaryOp -> r -> NExprF r
NUnary NUnaryOp
op

-- | Logical negation: @not@.
mkNot :: NExpr -> NExpr
mkNot :: NExpr -> NExpr
mkNot = NUnaryOp -> NExpr -> NExpr
mkOp NUnaryOp
NNot

-- | Number negation: @-@.
--
-- Negation in the language works with integers and floating point.
--  @since 0.15.0
mkNeg :: NExpr -> NExpr
mkNeg :: NExpr -> NExpr
mkNeg = NUnaryOp -> NExpr -> NExpr
mkOp NUnaryOp
NNeg

-- | Put a binary operator.
--  @since 0.15.0
mkOp2 :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
op NExpr
a = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. NBinaryOp -> r -> r -> NExprF r
NBinary NBinaryOp
op NExpr
a

-- | > { x }
--  @since 0.15.0
mkParamSet :: [(Text, Maybe NExpr)] -> Params NExpr
mkParamSet :: [(Text, Maybe NExpr)] -> Params NExpr
mkParamSet [(Text, Maybe NExpr)]
pset = Maybe Text -> [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkGeneralParamSet forall a. Maybe a
Nothing [(Text, Maybe NExpr)]
pset Bool
False

-- | > { x, ... }
--  @since 0.15.0
mkVariadicParamSet :: [(Text, Maybe NExpr)] -> Params NExpr
mkVariadicParamSet :: [(Text, Maybe NExpr)] -> Params NExpr
mkVariadicParamSet [(Text, Maybe NExpr)]
pset = Maybe Text -> [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkGeneralParamSet forall a. Maybe a
Nothing [(Text, Maybe NExpr)]
pset Bool
True

-- | > s@{ x }
--  @since 0.15.0
mkNamedParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr
mkNamedParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr
mkNamedParamSet Text
name [(Text, Maybe NExpr)]
pset = Maybe Text -> [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkGeneralParamSet (forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
name) [(Text, Maybe NExpr)]
pset Bool
False

-- | > s@{ x, ... }
--  @since 0.15.0
mkNamedVariadicParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr
mkNamedVariadicParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr
mkNamedVariadicParamSet Text
name [(Text, Maybe NExpr)]
params = Maybe Text -> [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkGeneralParamSet (forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
name) [(Text, Maybe NExpr)]
params Bool
True

-- | Args:
--
-- 1. Maybe name:
--
-- > Nothing  ->   {}
-- > Just "s" -> s@{}
--
-- 2. key:expr pairs
--
-- 3. Is variadic or not:
--
-- > True  -> {...}
-- > False -> {}
--  @since 0.15.0
mkGeneralParamSet :: Maybe Text -> [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkGeneralParamSet :: Maybe Text -> [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkGeneralParamSet Maybe Text
mname [(Text, Maybe NExpr)]
params Bool
variadic = forall r. Maybe VarName -> Variadic -> ParamSet r -> Params r
ParamSet (coerce :: forall a b. Coercible a b => a -> b
coerce Maybe Text
mname) (Variadic
Variadic forall a. Monoid a => a -> Bool -> a
`whenTrue` Bool
variadic) (coerce :: forall a b. Coercible a b => a -> b
coerce [(Text, Maybe NExpr)]
params)

-- | > rec { .. }
mkRecSet :: [Binding NExpr] -> NExpr
mkRecSet :: [Binding NExpr] -> NExpr
mkRecSet = Recursivity -> [Binding NExpr] -> NExpr
mkSet Recursivity
Recursive

-- | Put a non-recursive set.
--
-- > { .. }
mkNonRecSet :: [Binding NExpr] -> NExpr
mkNonRecSet :: [Binding NExpr] -> NExpr
mkNonRecSet = Recursivity -> [Binding NExpr] -> NExpr
mkSet forall a. Monoid a => a
mempty

-- | General set builder function.
mkSet :: Recursivity -> [Binding NExpr] -> NExpr
mkSet :: Recursivity -> [Binding NExpr] -> NExpr
mkSet Recursivity
r = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. Recursivity -> [Binding r] -> NExprF r
NSet Recursivity
r

-- | Empty set.
--
-- Monoid. Use @//@ operation (shorthand $//) to extend the set.
--  @since 0.15.0
emptySet :: NExpr
emptySet :: NExpr
emptySet = [Binding NExpr] -> NExpr
mkNonRecSet forall a. Monoid a => a
mempty

-- | Put a list.
mkList :: [NExpr] -> NExpr
mkList :: [NExpr] -> NExpr
mkList = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. [r] -> NExprF r
NList

--  @since 0.15.0
emptyList :: NExpr
emptyList :: NExpr
emptyList = [NExpr] -> NExpr
mkList forall a. Monoid a => a
mempty

-- | Wrap in a @let@.
--
-- (Evaluate the second argument after introducing the bindings.)
--
-- +------------------------+-----------------+
-- | Haskell                | Nix             |
-- +========================+=================+
-- | @mkLets bindings expr@ | @let bindings;@ |
-- |                        | @in expr@       |
-- +------------------------+-----------------+
mkLets :: [Binding NExpr] -> NExpr -> NExpr
mkLets :: [Binding NExpr] -> NExpr -> NExpr
mkLets [Binding NExpr]
bindings = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. [Binding r] -> r -> NExprF r
NLet [Binding NExpr]
bindings

-- | Create a @whith@:
-- 1st expr - what to bring into the scope.
-- 2nd - expression that recieves the scope extention.
--
-- +--------------------+-------------------+
-- | Haskell            | Nix               |
-- +====================+===================+
-- | @mkWith body main@ | @with body; expr@ |
-- +--------------------+-------------------+
mkWith :: NExpr -> NExpr -> NExpr
mkWith :: NExpr -> NExpr -> NExpr
mkWith NExpr
e = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. r -> r -> NExprF r
NWith NExpr
e

-- | Create an @assert@:
-- 1st expr - asserting itself, must return @true@.
-- 2nd - main expression to evaluated after assertion.
--
-- +-----------------------+----------------------+
-- | Haskell               | Nix                  |
-- +=======================+======================+
-- | @mkAssert check eval@ | @assert check; eval@ |
-- +-----------------------+----------------------+
mkAssert :: NExpr -> NExpr -> NExpr
mkAssert :: NExpr -> NExpr -> NExpr
mkAssert NExpr
e = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. r -> r -> NExprF r
NAssert NExpr
e

-- | Put:
--
-- > if expr1
-- >   then expr2
-- >   else expr3
mkIf :: NExpr -> NExpr -> NExpr -> NExpr
mkIf :: NExpr -> NExpr -> NExpr -> NExpr
mkIf NExpr
e1 NExpr
e2 = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. r -> r -> r -> NExprF r
NIf NExpr
e1 NExpr
e2

-- | Lambda function, analog of Haskell's @\\ x -> x@:
--
-- +-----------------------+-----------+
-- | Haskell               | Nix       |
-- +=======================+===========+
-- | @ mkFunction x expr @ | @x: expr@ |
-- +-----------------------+-----------+
mkFunction :: Params NExpr -> NExpr -> NExpr
mkFunction :: Params NExpr -> NExpr -> NExpr
mkFunction Params NExpr
params = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. Params r -> r -> NExprF r
NAbs Params NExpr
params

-- | General dot-reference with optional alternative if the key does not exist.
--  @since 0.15.0
getRefOrDefault :: Maybe NExpr -> NExpr -> Text -> NExpr
getRefOrDefault :: Maybe NExpr -> NExpr -> Text -> NExpr
getRefOrDefault Maybe NExpr
alt NExpr
obj = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. Maybe r -> r -> NAttrPath r -> NExprF r
NSelect Maybe NExpr
alt NExpr
obj forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> NAttrPath NExpr
mkSelector

-- ** Base functor builders for basic expressions builders *sic

-- | Unfixed @mkNull@.
mkNullF :: NExprF a
mkNullF :: forall a. NExprF a
mkNullF = forall r. NAtom -> NExprF r
NConstant NAtom
NNull

-- | Unfixed @mkBool@.
mkBoolF :: Bool -> NExprF a
mkBoolF :: forall a. Bool -> NExprF a
mkBoolF = forall r. NAtom -> NExprF r
NConstant forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> NAtom
NBool

-- | Unfixed @mkInt@.
mkIntF :: Integer -> NExprF a
mkIntF :: forall a. Integer -> NExprF a
mkIntF = forall r. NAtom -> NExprF r
NConstant forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> NAtom
NInt

-- | Unfixed @mkFloat@.
mkFloatF :: Float -> NExprF a
mkFloatF :: forall a. Float -> NExprF a
mkFloatF = forall r. NAtom -> NExprF r
NConstant forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> NAtom
NFloat

-- | Unfixed @mkPath@.
mkPathF :: Bool -> FilePath -> NExprF a
mkPathF :: forall a. Bool -> FilePath -> NExprF a
mkPathF Bool
False = forall r. Path -> NExprF r
NLiteralPath forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce
mkPathF Bool
True  = forall r. Path -> NExprF r
NEnvPath forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

-- | Unfixed @mkEnvPath@.
mkEnvPathF :: FilePath -> NExprF a
mkEnvPathF :: forall a. FilePath -> NExprF a
mkEnvPathF = forall a. Bool -> FilePath -> NExprF a
mkPathF Bool
True

-- | Unfixed @mkRelPath@.
mkRelPathF :: FilePath -> NExprF a
mkRelPathF :: forall a. FilePath -> NExprF a
mkRelPathF = forall a. Bool -> FilePath -> NExprF a
mkPathF Bool
False

-- | Unfixed @mkSym@.
mkSymF :: Text -> NExprF a
mkSymF :: forall a. Text -> NExprF a
mkSymF = forall r. VarName -> NExprF r
NSym forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

-- | Unfixed @mkSynHole@.
mkSynHoleF :: Text -> NExprF a
mkSynHoleF :: forall a. Text -> NExprF a
mkSynHoleF = forall r. VarName -> NExprF r
NSynHole forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce


-- * Other
-- (org this better/make a better name for section(s))

-- | An `inherit` clause with an expression to pull from.
--
-- +------------------------+--------------------+------------+
-- | Hask                   | Nix                | pseudocode |
-- +========================+====================+============+
-- | @inheritFrom x [a, b]@ | @inherit (x) a b;@ | @a = x.a;@ |
-- |                        |                    | @b = x.b;@ |
-- +------------------------+--------------------+------------+
inheritFrom :: e -> [VarName] -> Binding e
inheritFrom :: forall e. e -> [VarName] -> Binding e
inheritFrom e
expr [VarName]
ks = forall r. Maybe r -> [VarName] -> NSourcePos -> Binding r
Inherit (forall (f :: * -> *) a. Applicative f => a -> f a
pure e
expr) [VarName]
ks NSourcePos
nullPos

-- | An `inherit` clause without an expression to pull from.
--
-- +----------------------+----------------+------------------+
-- | Hask                 | Nix            | pseudocode       |
-- +======================+================+==================+
-- | @inheritFrom [a, b]@ | @inherit a b;@ | @a = outside.a;@ |
-- |                      |                | @b = outside.b;@ |
-- +----------------------+----------------+------------------+
inherit :: [VarName] -> Binding e
inherit :: forall e. [VarName] -> Binding e
inherit [VarName]
ks = forall r. Maybe r -> [VarName] -> NSourcePos -> Binding r
Inherit forall a. Maybe a
Nothing [VarName]
ks NSourcePos
nullPos

-- | Nix @=@ (bind operator).
($=) :: Text -> NExpr -> Binding NExpr
$= :: Text -> NExpr -> Binding NExpr
($=) = Text -> NExpr -> Binding NExpr
bindTo
infixr 2 $=

-- | Shorthand for producing a binding of a name to an expression: Nix's @=@.
bindTo :: Text -> NExpr -> Binding NExpr
bindTo :: Text -> NExpr -> Binding NExpr
bindTo Text
name NExpr
x = forall r. NAttrPath r -> r -> NSourcePos -> Binding r
NamedVar (Text -> NAttrPath NExpr
mkSelector Text
name) NExpr
x NSourcePos
nullPos

-- | Append a list of bindings to a set or let expression.
-- For example:
-- adding      `[a = 1, b = 2]`
-- to       `let               c = 3; in 4`
-- produces `let a = 1; b = 2; c = 3; in 4`.
appendBindings :: [Binding NExpr] -> NExpr -> NExpr
appendBindings :: [Binding NExpr] -> NExpr -> NExpr
appendBindings [Binding NExpr]
newBindings (Fix NExprF NExpr
e) =
  case NExprF NExpr
e of
    NLet [Binding NExpr]
bindings NExpr
e'    -> [Binding NExpr] -> NExpr -> NExpr
mkLets ([Binding NExpr]
bindings forall a. Semigroup a => a -> a -> a
<> [Binding NExpr]
newBindings) NExpr
e'
    NSet Recursivity
recur [Binding NExpr]
bindings -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall a b. (a -> b) -> a -> b
$ forall r. Recursivity -> [Binding r] -> NExprF r
NSet Recursivity
recur ([Binding NExpr]
bindings forall a. Semigroup a => a -> a -> a
<> [Binding NExpr]
newBindings)
    NExprF NExpr
_                   -> forall a t. (HasCallStack, IsText t) => t -> a
error Text
"Can only append bindings to a set or a let"

-- | Applies a transformation to the body of a Nix function.
modifyFunctionBody :: (NExpr -> NExpr) -> NExpr -> NExpr
modifyFunctionBody :: (NExpr -> NExpr) -> NExpr -> NExpr
modifyFunctionBody NExpr -> NExpr
transform (Fix (NAbs Params NExpr
params NExpr
body)) = Params NExpr -> NExpr -> NExpr
mkFunction Params NExpr
params forall a b. (a -> b) -> a -> b
$ NExpr -> NExpr
transform NExpr
body
modifyFunctionBody NExpr -> NExpr
_ NExpr
_ = forall a t. (HasCallStack, IsText t) => t -> a
error Text
"Not a function"

-- | A @let@ statement with multiple assignments.
letsE :: [(Text, NExpr)] -> NExpr -> NExpr
letsE :: [(Text, NExpr)] -> NExpr -> NExpr
letsE [(Text, NExpr)]
pairs = [Binding NExpr] -> NExpr -> NExpr
mkLets forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> NExpr -> Binding NExpr
($=) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Text, NExpr)]
pairs

-- | Wrapper for a single-variable @let@.
letE :: Text -> NExpr -> NExpr -> NExpr
letE :: Text -> NExpr -> NExpr -> NExpr
letE Text
varName NExpr
varExpr = [(Text, NExpr)] -> NExpr -> NExpr
letsE forall a b. (a -> b) -> a -> b
$ forall x. One x => OneItem x -> x
one (Text
varName, NExpr
varExpr)

-- | Make a non-recursive attribute set.
attrsE :: [(Text, NExpr)] -> NExpr
attrsE :: [(Text, NExpr)] -> NExpr
attrsE [(Text, NExpr)]
pairs = [Binding NExpr] -> NExpr
mkNonRecSet forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> NExpr -> Binding NExpr
($=) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Text, NExpr)]
pairs

-- | Make a recursive attribute set.
recAttrsE :: [(Text, NExpr)] -> NExpr
recAttrsE :: [(Text, NExpr)] -> NExpr
recAttrsE [(Text, NExpr)]
pairs = [Binding NExpr] -> NExpr
mkRecSet forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> NExpr -> Binding NExpr
($=) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Text, NExpr)]
pairs


-- * Nix binary operators

(@@), ($==), ($!=), ($<), ($<=), ($>), ($>=), ($&&), ($||), ($->), ($//), ($+), ($-), ($*), ($/), ($++)
  :: NExpr -> NExpr -> NExpr
--  2021-07-10: NOTE: Probably the presedence of some operators is still needs to be tweaked.

-- | Dot-reference into an attribute set: @attrSet.k@
(@.) :: NExpr -> Text -> NExpr
@. :: NExpr -> Text -> NExpr
(@.) = Maybe NExpr -> NExpr -> Text -> NExpr
getRefOrDefault forall a. Maybe a
Nothing
infix 9 @.

-- | Dot-reference into an attribute set with alternative if the key does not exist.
--
-- > s.x or y
--  @since 0.15.0
(@.<|>) :: NExpr -> Text -> NExpr -> NExpr
@.<|> :: NExpr -> Text -> NExpr -> NExpr
(@.<|>) NExpr
obj Text
name NExpr
alt = Maybe NExpr -> NExpr -> Text -> NExpr
getRefOrDefault (forall (f :: * -> *) a. Applicative f => a -> f a
pure NExpr
alt ) NExpr
obj Text
name
infix 9 @.<|>

-- | Function application (@' '@ in @f x@)
@@ :: NExpr -> NExpr -> NExpr
(@@) = NExpr -> NExpr -> NExpr
mkApp
infixl 8 @@

-- | List concatenation: @++@
$++ :: NExpr -> NExpr -> NExpr
($++) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NConcat
infixr 7 $++

-- | Multiplication: @*@
$* :: NExpr -> NExpr -> NExpr
($*)  = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NMult
infixl 6 $*

-- | Division: @/@
$/ :: NExpr -> NExpr -> NExpr
($/)  = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NDiv
infixl 6 $/

-- | Addition: @+@
$+ :: NExpr -> NExpr -> NExpr
($+)  = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NPlus
infixl 5 $+

-- | Subtraction: @-@
$- :: NExpr -> NExpr -> NExpr
($-)  = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NMinus
infixl 5 $-

-- | Extend/override the left attr set, with the right one: @//@
$// :: NExpr -> NExpr -> NExpr
($//) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NUpdate
infixr 5 $//

-- | Greater than: @>@
$> :: NExpr -> NExpr -> NExpr
($>)  = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NGt
infix 4 $>

-- | Greater than OR equal: @>=@
infix 4 $>=
$>= :: NExpr -> NExpr -> NExpr
($>=) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NGte

-- | Less than OR equal: @<=@
$<= :: NExpr -> NExpr -> NExpr
($<=) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NLte
infix 4 $<=

-- | Less than: @<@
$< :: NExpr -> NExpr -> NExpr
($<)  = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NLt
infix 4 $<

-- | Equality: @==@
$== :: NExpr -> NExpr -> NExpr
($==) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NEq
infix 3 $==

-- | Inequality: @!=@
$!= :: NExpr -> NExpr -> NExpr
($!=) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NNEq
infix 3 $!=

-- | AND: @&&@
$&& :: NExpr -> NExpr -> NExpr
($&&) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NAnd
infixl 2 $&&

-- | OR: @||@
$|| :: NExpr -> NExpr -> NExpr
($||) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NOr
infixl 2 $||

-- | Logical implication: @->@
$-> :: NExpr -> NExpr -> NExpr
($->) = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2 NBinaryOp
NImpl
infix 1 $->

-- | Lambda function, analog of Haskell's @\\ x -> x@:
--
-- +---------------+-----------+
-- | Haskell       | Nix       |
-- +===============+===========+
-- | @x ==> expr @ | @x: expr@ |
-- +---------------+-----------+
(==>) :: Params NExpr -> NExpr -> NExpr
==> :: Params NExpr -> NExpr -> NExpr
(==>) = Params NExpr -> NExpr -> NExpr
mkFunction
infixr 1 ==>


-- * Under deprecation

-- NOTE: Remove after 2023-07
-- | __@Deprecated@__: Please, use `mkOp`
-- Put an unary operator.
mkOper :: NUnaryOp -> NExpr -> NExpr
mkOper :: NUnaryOp -> NExpr -> NExpr
mkOper = NUnaryOp -> NExpr -> NExpr
mkOp

-- NOTE: Remove after 2023-07
-- | __@Deprecated@__: Please, use `mkOp2`
-- | Put a binary operator.
mkOper2 :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkOper2 :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkOper2 = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2

-- NOTE: Remove after 2023-07
-- | __@Deprecated@__: Please, use `mkOp2`
-- | Nix binary operator builder.
mkBinop :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkBinop :: NBinaryOp -> NExpr -> NExpr -> NExpr
mkBinop = NBinaryOp -> NExpr -> NExpr -> NExpr
mkOp2

-- NOTE: Remove after 2023-07
-- | __@Deprecated@__: Please, use:
--   * `mkParamSet` is for closed sets;
--   * `mkVariadicSet` is for variadic;
--   * `mkGeneralParamSet` a general constructor.
mkParamset :: [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkParamset :: [(Text, Maybe NExpr)] -> Bool -> Params NExpr
mkParamset [(Text, Maybe NExpr)]
params Bool
variadic = forall r. Maybe VarName -> Variadic -> ParamSet r -> Params r
ParamSet forall a. Maybe a
Nothing (Variadic
Variadic forall a. Monoid a => a -> Bool -> a
`whenTrue` Bool
variadic) (coerce :: forall a b. Coercible a b => a -> b
coerce [(Text, Maybe NExpr)]
params)