packages feed

hnix 0.14.0.8 → 0.15.0

raw patch · 63 files changed

+5833/−4398 lines, 63 filesdep +unix-compatdep −unixdep ~basedep ~hashablePVP ok

version bump matches the API change (PVP)

Dependencies added: unix-compat

Dependencies removed: unix

Dependency ranges changed: base, hashable

API changes (from Hackage documentation)

- Nix.Convert: Path :: FilePath -> Path
- Nix.Convert: [getPath] :: Path -> FilePath
- Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.FromValue a m (Nix.Value.NValue t f m)) => Nix.Convert.FromValue (Nix.Utils.AttrSet a) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
- Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.FromValue a m (Nix.Value.NValue t f m)) => Nix.Convert.FromValue (Nix.Utils.AttrSet a, Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
- Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.ToValue a m (Nix.Value.NValue t f m)) => Nix.Convert.ToValue (Nix.Utils.AttrSet a) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
- Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.ToValue a m (Nix.Value.NValue t f m)) => Nix.Convert.ToValue (Nix.Utils.AttrSet a, Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
- Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Value.Monad.MonadValue (Nix.Value.NValue t f m) m) => Nix.Convert.FromValue Nix.Convert.Path m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: instance GHC.Show.Show Nix.Convert.Path
- Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.FromValue (Nix.Utils.AttrSet (Nix.Value.NValue t f m)) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.FromValue (Nix.Utils.AttrSet (Nix.Value.NValue t f m), Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.FromValue GHC.Integer.Type.Integer m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue (Nix.Utils.AttrSet (Nix.Value.NValue t f m)) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue (Nix.Utils.AttrSet (Nix.Value.NValue t f m), Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue GHC.Integer.Type.Integer m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue Nix.Convert.Path m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
- Nix.Convert: newtype Path
- Nix.Effects: [unStorePath] :: StorePath -> FilePath
- Nix.Effects: makeAbsolutePath :: MonadEffects t f m => FilePath -> m FilePath
- Nix.Effects: type FilePathFilter m = FilePath -> m Bool
- Nix.Effects.Basic: defaultMakeAbsolutePath :: MonadNix e t f m => FilePath -> m FilePath
- Nix.Expr.Shorthands: infixl 1 @@
- Nix.Expr.Strings: removePlainEmpty :: [Antiquoted Text r] -> [Antiquoted Text r]
- Nix.Expr.Types: NNonRecursive :: NRecordType
- Nix.Expr.Types: NRecursive :: NRecordType
- Nix.Expr.Types: data NRecordType
- Nix.Expr.Types: instance Codec.Serialise.Class.Serialise Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance Control.DeepSeq.NFData Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance Data.Aeson.Types.FromJSON.FromJSON Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance Data.Aeson.Types.ToJSON.ToJSON Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance Data.Binary.Class.Binary Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance Data.Data.Data Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance Data.Hashable.Class.Hashable Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance GHC.Classes.Eq Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance GHC.Classes.Ord Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance GHC.Enum.Bounded Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance GHC.Enum.Enum Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance GHC.Generics.Generic Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance GHC.Read.Read Nix.Expr.Types.NRecordType
- Nix.Expr.Types: instance GHC.Show.Show Nix.Expr.Types.NRecordType
- Nix.Expr.Types: type VarName = Text
- Nix.Expr.Types.Annotated: Ann :: ann -> a -> Ann ann a
- Nix.Expr.Types.Annotated: annToAnnF :: Ann ann (f (Fix (AnnF ann f))) -> Fix (AnnF ann f)
- Nix.Expr.Types.Annotated: data Ann ann a
- Nix.Expr.Types.Annotated: instance (Codec.Serialise.Class.Serialise ann, Codec.Serialise.Class.Serialise a) => Codec.Serialise.Class.Serialise (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (Control.DeepSeq.NFData ann, Control.DeepSeq.NFData a) => Control.DeepSeq.NFData (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (Data.Binary.Class.Binary ann, Data.Binary.Class.Binary a) => Data.Binary.Class.Binary (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (Data.Data.Data ann, Data.Data.Data a) => Data.Data.Data (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (Data.Hashable.Class.Hashable ann, Data.Hashable.Class.Hashable a) => Data.Hashable.Class.Hashable (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (GHC.Classes.Eq ann, GHC.Classes.Eq a) => GHC.Classes.Eq (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (GHC.Classes.Ord ann, GHC.Classes.Ord a) => GHC.Classes.Ord (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (GHC.Read.Read ann, GHC.Read.Read a) => GHC.Read.Read (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance (GHC.Show.Show ann, GHC.Show.Show a) => GHC.Show.Show (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance Control.DeepSeq.NFData ann => Control.DeepSeq.NFData1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance Data.Aeson.Types.FromJSON.FromJSON ann => Data.Aeson.Types.FromJSON.FromJSON1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance Data.Aeson.Types.FromJSON.FromJSON2 Nix.Expr.Types.Annotated.Ann
- Nix.Expr.Types.Annotated: instance Data.Aeson.Types.ToJSON.ToJSON ann => Data.Aeson.Types.ToJSON.ToJSON1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance Data.Aeson.Types.ToJSON.ToJSON2 Nix.Expr.Types.Annotated.Ann
- Nix.Expr.Types.Annotated: instance Data.Foldable.Foldable (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Eq2 Nix.Expr.Types.Annotated.Ann
- Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Ord2 Nix.Expr.Types.Annotated.Ann
- Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Read2 Nix.Expr.Types.Annotated.Ann
- Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Show2 Nix.Expr.Types.Annotated.Ann
- Nix.Expr.Types.Annotated: instance Data.Hashable.Class.Hashable ann => Data.Hashable.Class.Hashable1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance Data.Traversable.Traversable (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance GHC.Base.Functor (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance GHC.Classes.Eq ann => Data.Functor.Classes.Eq1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance GHC.Classes.Ord ann => Data.Functor.Classes.Ord1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance GHC.Generics.Generic (Nix.Expr.Types.Annotated.Ann ann a)
- Nix.Expr.Types.Annotated: instance GHC.Generics.Generic1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance GHC.Read.Read ann => Data.Functor.Classes.Read1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: instance GHC.Show.Show ann => Data.Functor.Classes.Show1 (Nix.Expr.Types.Annotated.Ann ann)
- Nix.Expr.Types.Annotated: nAbs :: Ann SrcSpan (Params NExprLoc) -> NExprLoc -> NExprLoc
- Nix.Expr.Types.Annotated: nApp :: NExprLoc -> NExprLoc -> NExprLoc
- Nix.Expr.Types.Annotated: nBinary :: Ann SrcSpan NBinaryOp -> NExprLoc -> NExprLoc -> NExprLoc
- Nix.Expr.Types.Annotated: nHasAttr :: NExprLoc -> Ann SrcSpan (NAttrPath NExprLoc) -> NExprLoc
- Nix.Expr.Types.Annotated: nNull :: NExprLoc
- Nix.Expr.Types.Annotated: nSelectLoc :: NExprLoc -> Ann SrcSpan (NAttrPath NExprLoc) -> Maybe NExprLoc -> NExprLoc
- Nix.Expr.Types.Annotated: nStr :: Ann SrcSpan (NString NExprLoc) -> NExprLoc
- Nix.Expr.Types.Annotated: nUnary :: Ann SrcSpan NUnaryOp -> NExprLoc -> NExprLoc
- Nix.Expr.Types.Annotated: pattern AnnE :: forall ann (f :: Type -> Type). ann -> f (Fix (AnnF ann f)) -> Fix (AnnF ann f)
- Nix.Expr.Types.Annotated: pattern AnnFP :: ann -> f a -> Compose (Ann ann) f a
- Nix.Expr.Types.Annotated: pattern NAbs_ :: SrcSpan -> Params r -> r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NAssert_ :: SrcSpan -> r -> r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NBinary_ :: SrcSpan -> NBinaryOp -> r -> r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NConstant_ :: SrcSpan -> NAtom -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NEnvPath_ :: SrcSpan -> FilePath -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NHasAttr_ :: SrcSpan -> r -> NAttrPath r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NIf_ :: SrcSpan -> r -> r -> r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NLet_ :: SrcSpan -> [Binding r] -> r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NList_ :: SrcSpan -> [r] -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NLiteralPath_ :: SrcSpan -> FilePath -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NSelect_ :: SrcSpan -> r -> NAttrPath r -> Maybe r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NSet_ :: SrcSpan -> NRecordType -> [Binding r] -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NStr_ :: SrcSpan -> NString r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NSym_ :: SrcSpan -> VarName -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NSynHole_ :: SrcSpan -> Text -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NUnary_ :: SrcSpan -> NUnaryOp -> r -> NExprLocF r
- Nix.Expr.Types.Annotated: pattern NWith_ :: SrcSpan -> r -> r -> NExprLocF r
- Nix.Expr.Types.Annotated: stripAnn :: AnnF ann f r -> f r
- Nix.Frames: AllocationLimitExceeded :: AllocationLimitExceeded
- Nix.Frames: AssertionFailed :: String -> AssertionFailed
- Nix.Frames: BlockedIndefinitelyOnMVar :: BlockedIndefinitelyOnMVar
- Nix.Frames: BlockedIndefinitelyOnSTM :: BlockedIndefinitelyOnSTM
- Nix.Frames: CompactionFailed :: String -> CompactionFailed
- Nix.Frames: Deadlock :: Deadlock
- Nix.Frames: Denormal :: ArithException
- Nix.Frames: DivideByZero :: ArithException
- Nix.Frames: ErrorCallWithLocation :: String -> String -> ErrorCall
- Nix.Frames: Handler :: (e -> IO a) -> Handler a
- Nix.Frames: HeapOverflow :: AsyncException
- Nix.Frames: IndexOutOfBounds :: String -> ArrayException
- Nix.Frames: LossOfPrecision :: ArithException
- Nix.Frames: MaskedInterruptible :: MaskingState
- Nix.Frames: MaskedUninterruptible :: MaskingState
- Nix.Frames: NestedAtomically :: NestedAtomically
- Nix.Frames: NoMethodError :: String -> NoMethodError
- Nix.Frames: NonTermination :: NonTermination
- Nix.Frames: Overflow :: ArithException
- Nix.Frames: PatternMatchFail :: String -> PatternMatchFail
- Nix.Frames: RatioZeroDenominator :: ArithException
- Nix.Frames: RecConError :: String -> RecConError
- Nix.Frames: RecSelError :: String -> RecSelError
- Nix.Frames: RecUpdError :: String -> RecUpdError
- Nix.Frames: SomeAsyncException :: e -> SomeAsyncException
- Nix.Frames: SomeException :: e -> SomeException
- Nix.Frames: StackOverflow :: AsyncException
- Nix.Frames: ThreadKilled :: AsyncException
- Nix.Frames: TypeError :: String -> TypeError
- Nix.Frames: UndefinedElement :: String -> ArrayException
- Nix.Frames: Underflow :: ArithException
- Nix.Frames: Unmasked :: MaskingState
- Nix.Frames: UserInterrupt :: AsyncException
- Nix.Frames: allowInterrupt :: IO ()
- Nix.Frames: assert :: Bool -> a -> a
- Nix.Frames: asyncExceptionFromException :: Exception e => SomeException -> Maybe e
- Nix.Frames: asyncExceptionToException :: Exception e => e -> SomeException
- Nix.Frames: bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
- Nix.Frames: bracketOnError :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
- Nix.Frames: bracket_ :: IO a -> IO b -> IO c -> IO c
- Nix.Frames: catchJust :: Exception e => (e -> Maybe b) -> IO a -> (b -> IO a) -> IO a
- Nix.Frames: catches :: IO a -> [Handler a] -> IO a
- Nix.Frames: class (Typeable e, Show e) => Exception e
- Nix.Frames: data AllocationLimitExceeded
- Nix.Frames: data ArithException
- Nix.Frames: data ArrayException
- Nix.Frames: data AsyncException
- Nix.Frames: data BlockedIndefinitelyOnMVar
- Nix.Frames: data BlockedIndefinitelyOnSTM
- Nix.Frames: data Deadlock
- Nix.Frames: data ErrorCall
- Nix.Frames: data Handler a
- Nix.Frames: data IOException
- Nix.Frames: data MaskingState
- Nix.Frames: data NestedAtomically
- Nix.Frames: data NonTermination
- Nix.Frames: data SomeAsyncException
- Nix.Frames: data SomeException
- Nix.Frames: displayException :: Exception e => e -> String
- Nix.Frames: finally :: IO a -> IO b -> IO a
- Nix.Frames: fromException :: Exception e => SomeException -> Maybe e
- Nix.Frames: getMaskingState :: IO MaskingState
- Nix.Frames: handle :: Exception e => (e -> IO a) -> IO a -> IO a
- Nix.Frames: handleJust :: Exception e => (e -> Maybe b) -> (b -> IO a) -> IO a -> IO a
- Nix.Frames: interruptible :: IO a -> IO a
- Nix.Frames: ioError :: IOError -> IO a
- Nix.Frames: mapException :: (Exception e1, Exception e2) => (e1 -> e2) -> a -> a
- Nix.Frames: mask :: ((forall a. () => IO a -> IO a) -> IO b) -> IO b
- Nix.Frames: mask_ :: IO a -> IO a
- Nix.Frames: newtype AssertionFailed
- Nix.Frames: newtype CompactionFailed
- Nix.Frames: newtype NoMethodError
- Nix.Frames: newtype PatternMatchFail
- Nix.Frames: newtype RecConError
- Nix.Frames: newtype RecSelError
- Nix.Frames: newtype RecUpdError
- Nix.Frames: newtype TypeError
- Nix.Frames: onException :: IO a -> IO b -> IO a
- Nix.Frames: pattern ErrorCall :: String -> ErrorCall
- Nix.Frames: throw :: forall (r :: RuntimeRep) (a :: TYPE r) e. Exception e => e -> a
- Nix.Frames: throwIO :: Exception e => e -> IO a
- Nix.Frames: throwTo :: Exception e => ThreadId -> e -> IO ()
- Nix.Frames: toException :: Exception e => e -> SomeException
- Nix.Frames: try :: Exception e => IO a -> IO (Either e a)
- Nix.Frames: tryJust :: Exception e => (e -> Maybe b) -> IO a -> IO (Either b a)
- Nix.Frames: uninterruptibleMask :: ((forall a. () => IO a -> IO a) -> IO b) -> IO b
- Nix.Frames: uninterruptibleMask_ :: IO a -> IO a
- Nix.Fresh: [unFreshIdT] :: FreshIdT i m a -> ReaderT (Ref m i) m a
- Nix.Lint: instance Nix.Convert.FromValue (Nix.Utils.AttrSet (Nix.Lint.Symbolic m), Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) m (Nix.Lint.Symbolic m)
- Nix.Lint: instance Nix.Convert.ToValue (Nix.Utils.AttrSet (Nix.Lint.Symbolic m), Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) m (Nix.Lint.Symbolic m)
- Nix.Parser: nixToplevelForm :: Parser NExprLoc
- Nix.Parser: symbol :: Text -> Parser Text
- Nix.Reduce: instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (GHC.Maybe.Maybe GHC.IO.FilePath, Nix.Scope.Scopes (Nix.Reduce.Reducer m) Nix.Expr.Types.Annotated.NExprLoc) (Nix.Reduce.Reducer m)
- Nix.Reduce: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Data.HashMap.Internal.HashMap GHC.IO.FilePath Nix.Expr.Types.Annotated.NExprLoc, Data.HashMap.Internal.HashMap Data.Text.Internal.Text Data.Text.Internal.Text) (Nix.Reduce.Reducer m)
- Nix.Render: instance (Nix.Utils.Fix1.MonadFix1T t m, Control.Monad.Fail.MonadFail (Nix.Utils.Fix1.Fix1T t m), Nix.Render.MonadFile m) => Nix.Render.MonadFile (Nix.Utils.Fix1.Fix1T t m)
- Nix.Scope: [getScope] :: Scope a -> AttrSet a
- Nix.Scope: newScope :: AttrSet a -> Scope a
- Nix.Standard: [_stdCited] :: StdCited m a -> Cited (StdThunk m) (StdCited m) m a
- Nix.Standard: [_stdThunk] :: StdThunk (m :: Type -> Type) -> StdCited m (NThunkF m (StdValue m))
- Nix.Standard: instance (Control.Monad.Fix.MonadFix m, Nix.Render.MonadFile m, Control.Monad.Catch.MonadCatch m, Nix.Effects.MonadEnv m, Nix.Effects.MonadPaths m, Nix.Effects.MonadExec m, Nix.Effects.MonadHttp m, Nix.Effects.MonadInstantiate m, Nix.Effects.MonadIntrospect m, GHC.Base.MonadPlus m, Nix.Effects.MonadPutStr m, Nix.Effects.MonadStore m, Control.Monad.Ref.MonadAtomicRef m, Data.Typeable.Internal.Typeable m, Nix.Scope.Scoped (Nix.Standard.StdValue m) m, Control.Monad.Reader.Class.MonadReader (Nix.Context.Context m (Nix.Standard.StdValue m)) m, Control.Monad.State.Class.MonadState (Data.HashMap.Internal.HashMap GHC.IO.FilePath Nix.Expr.Types.Annotated.NExprLoc, Data.HashMap.Internal.HashMap Data.Text.Internal.Text Data.Text.Internal.Text) m, Nix.Value.MonadDataErrorContext (Nix.Standard.StdThunk m) (Nix.Standard.StdCited m) m, Nix.Thunk.MonadThunk (Nix.Standard.StdThunk m) m (Nix.Standard.StdValue m), Nix.Value.Monad.MonadValue (Nix.Standard.StdValue m) m) => Nix.Effects.MonadEffects (Nix.Standard.StdThunk m) (Nix.Standard.StdCited m) m
- Nix.Standard: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Data.HashMap.Internal.HashMap GHC.IO.FilePath Nix.Expr.Types.Annotated.NExprLoc, Data.HashMap.Internal.HashMap Data.Text.Internal.Text Data.Text.Internal.Text) (Nix.Standard.StandardTF r m)
- Nix.Standard: instance Nix.Thunk.MonadThunkId m => Nix.Thunk.MonadThunkId (Nix.Utils.Fix1.Fix1T Nix.Standard.StandardTF m)
- Nix.String: makeNixString :: Text -> HashSet StringContext -> NixString
- Nix.String: makeNixStringWithSingletonContext :: Text -> StringContext -> NixString
- Nix.String: makeNixStringWithoutContext :: Text -> NixString
- Nix.TH: instance Nix.TH.ToExpr GHC.Integer.Type.Integer
- Nix.Type.Assumption: [assumptions] :: Assumption -> [(Name, Type)]
- Nix.Type.Assumption: mergeAssumptions :: [Assumption] -> Assumption
- Nix.Type.Infer: instance Nix.Type.Infer.MonadInfer m => Nix.Convert.FromValue (Nix.Utils.AttrSet (Nix.Type.Infer.Judgment s), Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) (Nix.Type.Infer.InferT s m) (Nix.Type.Infer.Judgment s)
- Nix.Type.Infer: instance Nix.Type.Infer.MonadInfer m => Nix.Convert.ToValue (Nix.Utils.AttrSet (Nix.Type.Infer.Judgment s), Nix.Utils.AttrSet Text.Megaparsec.Pos.SourcePos) (Nix.Type.Infer.InferT s m) (Nix.Type.Infer.Judgment s)
- Nix.Type.Type: type Name = Text
- Nix.Utils: (%~) :: Setter s t a b -> (a -> b) -> s -> t
- Nix.Utils: (&&~) :: Setter s t Bool Bool -> Bool -> s -> t
- Nix.Utils: (*~) :: Num a => Setter s t a a -> a -> s -> t
- Nix.Utils: (+~) :: Num a => Setter s t a a -> a -> s -> t
- Nix.Utils: (-~) :: Num a => Setter s t a a -> a -> s -> t
- Nix.Utils: (.~) :: Setter s t a b -> b -> s -> t
- Nix.Utils: (//~) :: Fractional a => Setter s t a a -> a -> s -> t
- Nix.Utils: (<>~) :: Monoid a => Setter s t a a -> a -> s -> t
- Nix.Utils: (^.) :: s -> FoldLike a s t a b -> a
- Nix.Utils: (^..) :: s -> Fold s t a b -> [a]
- Nix.Utils: (^?) :: s -> Fold s t a b -> Maybe a
- Nix.Utils: (||~) :: Setter s t Bool Bool -> Bool -> s -> t
- Nix.Utils: PathEntryPath :: NixPathEntryType
- Nix.Utils: PathEntryURI :: NixPathEntryType
- Nix.Utils: _unFix :: Functor f1 => (f2 (Fix f2) -> f1 (f3 (Fix f3))) -> Fix f2 -> f1 (Fix f3)
- Nix.Utils: adiM :: (Traversable t, Monad m) => Transform t (m a) -> AlgM t m a -> Fix t -> m a
- Nix.Utils: allOf :: Fold s t a b -> (a -> Bool) -> s -> Bool
- Nix.Utils: alterF :: (Eq k, Hashable k, Functor f) => (Maybe v -> f (Maybe v)) -> k -> HashMap k v -> f (HashMap k v)
- Nix.Utils: anyOf :: Fold s t a b -> (a -> Bool) -> s -> Bool
- Nix.Utils: cataP :: Functor f => (Fix f -> f a -> a) -> Fix f -> a
- Nix.Utils: cataPM :: (Traversable f, Monad m) => (Fix f -> f a -> m a) -> Fix f -> m a
- Nix.Utils: class (Traversable f, Applicative f) => Identical (f :: Type -> Type)
- Nix.Utils: class Functor f => Phantom (f :: Type -> Type)
- Nix.Utils: data Constant a (b :: k)
- Nix.Utils: data NixPathEntryType
- Nix.Utils: degrating :: Grate s t a b -> ((s -> a) -> b) -> t
- Nix.Utils: firstOf :: Fold s t a b -> s -> Maybe a
- Nix.Utils: fixToFree :: Functor f => Fix f -> Free f a
- Nix.Utils: folding :: Foldable f => (s -> f a) -> Fold s t a b
- Nix.Utils: freeToFix :: Functor f => (a -> Fix f) -> Free f a -> Fix f
- Nix.Utils: infixl 8 ^.
- Nix.Utils: infixr 4 %~
- Nix.Utils: instance GHC.Classes.Eq Nix.Utils.NixPathEntryType
- Nix.Utils: instance GHC.Show.Show Nix.Utils.NixPathEntryType
- Nix.Utils: lastOf :: Fold s t a b -> s -> Maybe a
- Nix.Utils: lengthOf :: Num r => Fold s t a b -> s -> r
- Nix.Utils: loeb :: Functor f => f (f a -> a) -> f a
- Nix.Utils: matching :: Traversal s t a b -> s -> Either t a
- Nix.Utils: nullOf :: Fold s t a b -> s -> Bool
- Nix.Utils: para :: Functor f => (f (Fix f, a) -> a) -> Fix f -> a
- Nix.Utils: paraM :: (Traversable f, Monad m) => (f (Fix f, a) -> m a) -> Fix f -> m a
- Nix.Utils: productOf :: Num a => Fold s t a b -> s -> a
- Nix.Utils: reset :: Resetter s t a b -> b -> s -> t
- Nix.Utils: review :: GrateLike (Constant () :: Type -> Type) s t a b -> b -> t
- Nix.Utils: set :: Setter s t a b -> b -> s -> t
- Nix.Utils: sumOf :: Num a => Fold s t a b -> s -> a
- Nix.Utils: to :: (s -> a) -> Getter s t a b
- Nix.Utils: toEncodingSorted :: Value -> Encoding
- Nix.Utils: toListOf :: Fold s t a b -> s -> [a]
- Nix.Utils: type AdapterLike (f :: Type -> Type) (g :: Type -> Type) s t a b = g a -> f b -> g s -> f t
- Nix.Utils: type AdapterLike' (f :: Type -> Type) (g :: Type -> Type) s a = g a -> f a -> g s -> f s
- Nix.Utils: type AlgM f m a = f a -> m a
- Nix.Utils: type AttrSet = HashMap Text
- Nix.Utils: type FoldLike r s t a b = LensLike Constant r :: Type -> Type s t a b
- Nix.Utils: type FoldLike' r s a = LensLike' Constant r :: Type -> Type s a
- Nix.Utils: type GrateLike (g :: Type -> Type) s t a b = g a -> b -> g s -> t
- Nix.Utils: type GrateLike' (g :: Type -> Type) s a = g a -> a -> g s -> s
- Nix.Utils: type LensLike (f :: Type -> Type) s t a b = a -> f b -> s -> f t
- Nix.Utils: under :: Resetter s t a b -> (a -> b) -> s -> t
- Nix.Utils: uriAwareSplit :: Text -> [(Text, NixPathEntryType)]
- Nix.Utils: views :: FoldLike r s t a b -> (a -> r) -> s -> r
- Nix.Utils: whenFree :: Monoid b => (f (Free f a) -> b) -> Free f a -> b
- Nix.Utils: whenPure :: Monoid b => (a -> b) -> Free f a -> b
- Nix.Utils: zipWithOf :: Grate s t a b -> (a -> a -> b) -> s -> s -> t
- Nix.Value: pattern NVSet :: forall (w :: Type -> Type) t (m :: Type -> Type) a. Comonad w => AttrSet (Free (NValue' t w m) a) -> AttrSet SourcePos -> Free (NValue' t w m) a
- Nix.Value: pattern NVPath :: forall (w :: Type -> Type) t (m :: Type -> Type) a. Comonad w => FilePath -> Free (NValue' t w m) a
- Nix.Value: pattern NVBuiltin :: forall (w :: Type -> Type) t m a. Comonad w => Text -> (NValue t w m -> m (Free (NValue' t w m) a)) -> Free (NValue' t w m) a
+ Nix.Builtins: instance GHC.Classes.Eq Nix.Builtins.NixPathEntryType
+ Nix.Builtins: instance GHC.Show.Show Nix.Builtins.NixPathEntryType
+ Nix.Convert: inHask :: forall a1 a2 v b m. (Monad m, FromValue a1 m v, ToValue a2 m b) => (a1 -> a2) -> v -> m b
+ Nix.Convert: inHaskM :: forall a1 a2 v b m. (Monad m, FromValue a1 m v, ToValue a2 m b) => (a1 -> m a2) -> v -> m b
+ Nix.Convert: inHaskMay :: forall a1 a2 v b m. (Monad m, FromValue a1 m v, ToValue a2 m b) => (Maybe a1 -> a2) -> v -> m b
+ Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.FromValue a m (Nix.Value.NValue t f m)) => Nix.Convert.FromValue (Nix.Expr.Types.AttrSet a) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
+ Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.FromValue a m (Nix.Value.NValue t f m)) => Nix.Convert.FromValue (Nix.Expr.Types.AttrSet a, Nix.Expr.Types.PositionSet) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
+ Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.ToValue a m (Nix.Value.NValue t f m)) => Nix.Convert.ToValue (Nix.Expr.Types.AttrSet a) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
+ Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Convert.ToValue a m (Nix.Value.NValue t f m)) => Nix.Convert.ToValue (Nix.Expr.Types.AttrSet a, Nix.Expr.Types.PositionSet) m (Nix.Convert.Deeper (Nix.Value.NValue' t f m (Nix.Value.NValue t f m)))
+ Nix.Convert: instance (Nix.Convert.Convertible e t f m, Nix.Value.Monad.MonadValue (Nix.Value.NValue t f m) m) => Nix.Convert.FromValue Nix.Utils.Path m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.FromValue (Nix.Expr.Types.AttrSet (Nix.Value.NValue t f m)) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.FromValue (Nix.Expr.Types.AttrSet (Nix.Value.NValue t f m), Nix.Expr.Types.PositionSet) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.FromValue Data.Text.Internal.Text m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.FromValue GHC.Num.Integer.Integer m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue (Nix.Expr.Types.AttrSet (Nix.Value.NValue t f m)) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue (Nix.Expr.Types.AttrSet (Nix.Value.NValue t f m), Nix.Expr.Types.PositionSet) m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue Data.Text.Internal.Text m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue GHC.Num.Integer.Integer m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: instance Nix.Convert.Convertible e t f m => Nix.Convert.ToValue Nix.Utils.Path m (Nix.Value.NValue' t f m (Nix.Value.NValue t f m))
+ Nix.Convert: traverseFromM :: (Applicative m, Traversable t, FromValue b m a) => t a -> m (Maybe (t b))
+ Nix.Convert: traverseToValue :: (Traversable t, Applicative f, ToValue a f b) => t a -> f (t b)
+ Nix.Effects: toAbsolutePath :: MonadEffects t f m => Path -> m Path
+ Nix.Effects: type PathFilter m = Path -> m Bool
+ Nix.Effects.Basic: defaultToAbsolutePath :: forall e t f m. MonadNix e t f m => Path -> m Path
+ Nix.Expr.Shorthands: (@.<|>) :: NExpr -> Text -> NExpr -> NExpr
+ Nix.Expr.Shorthands: emptyList :: NExpr
+ Nix.Expr.Shorthands: emptySet :: NExpr
+ Nix.Expr.Shorthands: getRefOrDefault :: Maybe NExpr -> NExpr -> Text -> NExpr
+ Nix.Expr.Shorthands: infix 1 $->
+ Nix.Expr.Shorthands: infix 3 $!=
+ Nix.Expr.Shorthands: infix 4 $>=
+ Nix.Expr.Shorthands: infix 9 @.<|>
+ Nix.Expr.Shorthands: infixl 5 $-
+ Nix.Expr.Shorthands: infixl 6 $/
+ Nix.Expr.Shorthands: infixl 8 @@
+ Nix.Expr.Shorthands: infixr 5 $//
+ Nix.Expr.Shorthands: infixr 7 $++
+ Nix.Expr.Shorthands: mkConst :: NAtom -> NExpr
+ Nix.Expr.Shorthands: mkGeneralParamSet :: Maybe Text -> [(Text, Maybe NExpr)] -> Bool -> Params NExpr
+ Nix.Expr.Shorthands: mkNamedParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr
+ Nix.Expr.Shorthands: mkNamedVariadicParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr
+ Nix.Expr.Shorthands: mkNeg :: NExpr -> NExpr
+ Nix.Expr.Shorthands: mkOp :: NUnaryOp -> NExpr -> NExpr
+ Nix.Expr.Shorthands: mkOp2 :: NBinaryOp -> NExpr -> NExpr -> NExpr
+ Nix.Expr.Shorthands: mkParamSet :: [(Text, Maybe NExpr)] -> Params NExpr
+ Nix.Expr.Shorthands: mkSet :: Recursivity -> [Binding NExpr] -> NExpr
+ Nix.Expr.Shorthands: mkVariadicParamSet :: [(Text, Maybe NExpr)] -> Params NExpr
+ Nix.Expr.Strings: removeEmptyPlains :: [Antiquoted Text r] -> [Antiquoted Text r]
+ Nix.Expr.Types: Closed :: Variadic
+ Nix.Expr.Types: NonRecursive :: Recursivity
+ Nix.Expr.Types: Recursive :: Recursivity
+ Nix.Expr.Types: VarName :: Text -> VarName
+ Nix.Expr.Types: Variadic :: Variadic
+ Nix.Expr.Types: data Recursivity
+ Nix.Expr.Types: data Variadic
+ Nix.Expr.Types: instance Codec.Serialise.Class.Serialise Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance Codec.Serialise.Class.Serialise Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance Codec.Serialise.Class.Serialise Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Control.DeepSeq.NFData Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance Control.DeepSeq.NFData Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance Control.DeepSeq.NFData Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Data.Aeson.Types.FromJSON.FromJSON Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance Data.Aeson.Types.FromJSON.FromJSON Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance Data.Aeson.Types.FromJSON.FromJSON Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Data.Aeson.Types.ToJSON.ToJSON Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance Data.Aeson.Types.ToJSON.ToJSON Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance Data.Aeson.Types.ToJSON.ToJSON Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Data.Binary.Class.Binary Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance Data.Binary.Class.Binary Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance Data.Binary.Class.Binary Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Data.Data.Data Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance Data.Data.Data Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance Data.Data.Data Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Data.Hashable.Class.Hashable Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance Data.Hashable.Class.Hashable Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance Data.Hashable.Class.Hashable Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Data.String.IsString Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance GHC.Base.Monoid Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Base.Monoid Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance GHC.Base.Semigroup Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Base.Semigroup Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance GHC.Classes.Eq Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Classes.Eq Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance GHC.Classes.Eq Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance GHC.Classes.Ord Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Classes.Ord Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance GHC.Classes.Ord Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance GHC.Enum.Bounded Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Enum.Enum Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Generics.Generic Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Generics.Generic Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance GHC.Generics.Generic Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance GHC.Read.Read Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Read.Read Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance GHC.Read.Read Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance GHC.Show.Show Nix.Expr.Types.Recursivity
+ Nix.Expr.Types: instance GHC.Show.Show Nix.Expr.Types.VarName
+ Nix.Expr.Types: instance GHC.Show.Show Nix.Expr.Types.Variadic
+ Nix.Expr.Types: instance Relude.String.Conversion.ToString Nix.Expr.Types.VarName
+ Nix.Expr.Types: newtype VarName
+ Nix.Expr.Types: stringParts :: NString r -> [Antiquoted Text r]
+ Nix.Expr.Types: type AttrSet = HashMap VarName
+ Nix.Expr.Types: type PositionSet = HashMap VarName SourcePos
+ Nix.Expr.Types.Annotated: AnnUnit :: ann -> expr -> AnnUnit ann expr
+ Nix.Expr.Types.Annotated: annNAbs :: AnnUnit SrcSpan (Params NExprLoc) -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: annNApp :: NExprLoc -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: annNBinary :: AnnUnit SrcSpan NBinaryOp -> NExprLoc -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: annNHasAttr :: NExprLoc -> AnnUnit SrcSpan (NAttrPath NExprLoc) -> NExprLoc
+ Nix.Expr.Types.Annotated: annNNull :: NExprLoc
+ Nix.Expr.Types.Annotated: annNSelect :: Maybe NExprLoc -> NExprLoc -> AnnUnit SrcSpan (NAttrPath NExprLoc) -> NExprLoc
+ Nix.Expr.Types.Annotated: annNStr :: AnnUnit SrcSpan (NString NExprLoc) -> NExprLoc
+ Nix.Expr.Types.Annotated: annNUnary :: AnnUnit SrcSpan NUnaryOp -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: annUnitToAnn :: AnnUnit ann (f (Ann ann f)) -> Ann ann f
+ Nix.Expr.Types.Annotated: data AnnUnit ann expr
+ Nix.Expr.Types.Annotated: instance (Codec.Serialise.Class.Serialise ann, Codec.Serialise.Class.Serialise a) => Codec.Serialise.Class.Serialise (Nix.Expr.Types.Annotated.AnnUnit ann a)
+ Nix.Expr.Types.Annotated: instance (Control.DeepSeq.NFData ann, Control.DeepSeq.NFData expr) => Control.DeepSeq.NFData (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance (Data.Binary.Class.Binary ann, Data.Binary.Class.Binary a) => Data.Binary.Class.Binary (Nix.Expr.Types.Annotated.AnnUnit ann a)
+ Nix.Expr.Types.Annotated: instance (Data.Data.Data ann, Data.Data.Data expr) => Data.Data.Data (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance (Data.Hashable.Class.Hashable ann, Data.Hashable.Class.Hashable expr) => Data.Hashable.Class.Hashable (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance (GHC.Classes.Eq ann, GHC.Classes.Eq expr) => GHC.Classes.Eq (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance (GHC.Classes.Ord ann, GHC.Classes.Ord expr) => GHC.Classes.Ord (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance (GHC.Read.Read ann, GHC.Read.Read expr) => GHC.Read.Read (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance (GHC.Show.Show ann, GHC.Show.Show expr) => GHC.Show.Show (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance Control.DeepSeq.NFData ann => Control.DeepSeq.NFData1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance Data.Aeson.Types.FromJSON.FromJSON ann => Data.Aeson.Types.FromJSON.FromJSON1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance Data.Aeson.Types.FromJSON.FromJSON2 Nix.Expr.Types.Annotated.AnnUnit
+ Nix.Expr.Types.Annotated: instance Data.Aeson.Types.ToJSON.ToJSON ann => Data.Aeson.Types.ToJSON.ToJSON1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance Data.Aeson.Types.ToJSON.ToJSON2 Nix.Expr.Types.Annotated.AnnUnit
+ Nix.Expr.Types.Annotated: instance Data.Foldable.Foldable (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Eq2 Nix.Expr.Types.Annotated.AnnUnit
+ Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Ord2 Nix.Expr.Types.Annotated.AnnUnit
+ Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Read2 Nix.Expr.Types.Annotated.AnnUnit
+ Nix.Expr.Types.Annotated: instance Data.Functor.Classes.Show2 Nix.Expr.Types.Annotated.AnnUnit
+ Nix.Expr.Types.Annotated: instance Data.Hashable.Class.Hashable ann => Data.Hashable.Class.Hashable1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance Data.Traversable.Traversable (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance GHC.Base.Functor (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance GHC.Classes.Eq ann => Data.Functor.Classes.Eq1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance GHC.Classes.Ord ann => Data.Functor.Classes.Ord1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance GHC.Generics.Generic (Nix.Expr.Types.Annotated.AnnUnit ann expr)
+ Nix.Expr.Types.Annotated: instance GHC.Generics.Generic1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance GHC.Read.Read ann => Data.Functor.Classes.Read1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: instance GHC.Show.Show ann => Data.Functor.Classes.Show1 (Nix.Expr.Types.Annotated.AnnUnit ann)
+ Nix.Expr.Types.Annotated: pattern Ann :: forall ann (f :: Type -> Type). ann -> f (Ann ann f) -> Ann ann f
+ Nix.Expr.Types.Annotated: pattern AnnF :: ann -> f a -> Compose (AnnUnit ann) f a
+ Nix.Expr.Types.Annotated: pattern NAbsAnn :: SrcSpan -> Params NExprLoc -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NAbsAnnF :: SrcSpan -> Params r -> r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NAssertAnn :: SrcSpan -> NExprLoc -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NAssertAnnF :: SrcSpan -> r -> r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NBinaryAnn :: SrcSpan -> NBinaryOp -> NExprLoc -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NBinaryAnnF :: SrcSpan -> NBinaryOp -> r -> r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NConstantAnn :: SrcSpan -> NAtom -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NConstantAnnF :: SrcSpan -> NAtom -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NEnvPathAnn :: SrcSpan -> Path -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NEnvPathAnnF :: SrcSpan -> Path -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NHasAttrAnn :: SrcSpan -> NExprLoc -> NAttrPath NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NHasAttrAnnF :: SrcSpan -> r -> NAttrPath r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NIfAnn :: SrcSpan -> NExprLoc -> NExprLoc -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NIfAnnF :: SrcSpan -> r -> r -> r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NLetAnn :: SrcSpan -> [Binding NExprLoc] -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NLetAnnF :: SrcSpan -> [Binding r] -> r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NListAnn :: SrcSpan -> [NExprLoc] -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NListAnnF :: SrcSpan -> [r] -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NLiteralPathAnn :: SrcSpan -> Path -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NLiteralPathAnnF :: SrcSpan -> Path -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NSelectAnn :: SrcSpan -> Maybe NExprLoc -> NExprLoc -> NAttrPath NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NSelectAnnF :: SrcSpan -> Maybe r -> r -> NAttrPath r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NSetAnn :: SrcSpan -> Recursivity -> [Binding NExprLoc] -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NSetAnnF :: SrcSpan -> Recursivity -> [Binding r] -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NStrAnn :: SrcSpan -> NString NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NStrAnnF :: SrcSpan -> NString r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NSymAnn :: SrcSpan -> VarName -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NSymAnnF :: SrcSpan -> VarName -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NSynHoleAnn :: SrcSpan -> VarName -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NSynHoleAnnF :: SrcSpan -> VarName -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NUnaryAnn :: SrcSpan -> NUnaryOp -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NUnaryAnnF :: SrcSpan -> NUnaryOp -> r -> NExprLocF r
+ Nix.Expr.Types.Annotated: pattern NWithAnn :: SrcSpan -> NExprLoc -> NExprLoc -> NExprLoc
+ Nix.Expr.Types.Annotated: pattern NWithAnnF :: SrcSpan -> r -> r -> NExprLocF r
+ Nix.Expr.Types.Annotated: stripAnnF :: AnnF ann f r -> f r
+ Nix.Expr.Types.Annotated: type Ann ann f = Fix (AnnF ann f)
+ Nix.Json: toEncodingSorted :: Value -> Encoding
+ Nix.Lint: instance Nix.Convert.FromValue (Nix.Expr.Types.AttrSet (Nix.Lint.Symbolic m), Nix.Expr.Types.PositionSet) m (Nix.Lint.Symbolic m)
+ Nix.Lint: instance Nix.Convert.ToValue (Nix.Expr.Types.AttrSet (Nix.Lint.Symbolic m), Nix.Expr.Types.PositionSet) m (Nix.Lint.Symbolic m)
+ Nix.Parser: nixExprAlgebra :: Parser NExprLoc
+ Nix.Pretty: prettyVarName :: VarName -> Doc ann
+ Nix.Reduce: instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (GHC.Maybe.Maybe Nix.Utils.Path, Nix.Scope.Scopes (Nix.Reduce.Reducer m) Nix.Expr.Types.Annotated.NExprLoc) (Nix.Reduce.Reducer m)
+ Nix.Reduce: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Data.HashMap.Internal.HashMap Nix.Utils.Path Nix.Expr.Types.Annotated.NExprLoc, Data.HashMap.Internal.HashMap Data.Text.Internal.Text Data.Text.Internal.Text) (Nix.Reduce.Reducer m)
+ Nix.Render: instance (Nix.Utils.Fix1.MonadFix1T t m, Control.Monad.IO.Class.MonadIO (Nix.Utils.Fix1.Fix1T t m), Control.Monad.Fail.MonadFail (Nix.Utils.Fix1.Fix1T t m), Nix.Render.MonadFile m) => Nix.Render.MonadFile (Nix.Utils.Fix1.Fix1T t m)
+ Nix.Render.Frame: dumbRenderValue :: forall e t f m ann. (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m) => NValue t f m -> m (Doc ann)
+ Nix.Scope: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Nix.Scope.Scope a)
+ Nix.Scope: instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Nix.Scope.Scope a)
+ Nix.Scope: instance GHC.Base.Monoid (Nix.Scope.Scope a)
+ Nix.Scope: instance GHC.Base.Semigroup (Nix.Scope.Scope a)
+ Nix.Scope: instance GHC.Classes.Ord a => GHC.Classes.Ord (Nix.Scope.Scope a)
+ Nix.Scope: instance GHC.Generics.Generic (Nix.Scope.Scope a)
+ Nix.Scope: instance GHC.Read.Read a => GHC.Read.Read (Nix.Scope.Scope a)
+ Nix.Standard: instance (Control.Monad.Fix.MonadFix m, Nix.Render.MonadFile m, Control.Monad.Catch.MonadCatch m, Nix.Effects.MonadEnv m, Nix.Effects.MonadPaths m, Nix.Effects.MonadExec m, Nix.Effects.MonadHttp m, Nix.Effects.MonadInstantiate m, Nix.Effects.MonadIntrospect m, GHC.Base.MonadPlus m, Nix.Effects.MonadPutStr m, Nix.Effects.MonadStore m, Control.Monad.Ref.MonadAtomicRef m, Data.Typeable.Internal.Typeable m, Nix.Scope.Scoped (Nix.Standard.StdValue m) m, Control.Monad.Reader.Class.MonadReader (Nix.Context.Context m (Nix.Standard.StdValue m)) m, Control.Monad.State.Class.MonadState (Data.HashMap.Internal.HashMap Nix.Utils.Path Nix.Expr.Types.Annotated.NExprLoc, Data.HashMap.Internal.HashMap Data.Text.Internal.Text Data.Text.Internal.Text) m, Nix.Value.MonadDataErrorContext (Nix.Standard.StdThunk m) (Nix.Standard.StdCited m) m, Nix.Thunk.MonadThunk (Nix.Standard.StdThunk m) m (Nix.Standard.StdValue m), Nix.Value.Monad.MonadValue (Nix.Standard.StdValue m) m) => Nix.Effects.MonadEffects (Nix.Standard.StdThunk m) (Nix.Standard.StdCited m) m
+ Nix.Standard: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (Data.HashMap.Internal.HashMap Nix.Utils.Path Nix.Expr.Types.Annotated.NExprLoc, Data.HashMap.Internal.HashMap Data.Text.Internal.Text Data.Text.Internal.Text) (Nix.Standard.StandardTF r m)
+ Nix.Standard: instance Nix.Thunk.MonadThunkId m => Nix.Thunk.MonadThunkId (Nix.Standard.StandardT m)
+ Nix.Standard: type CitedStdThunk m = Cited (StdThunk m) (StdCited m) m (NThunkF m (StdValue m))
+ Nix.String: mkNixString :: Text -> HashSet StringContext -> NixString
+ Nix.String: mkNixStringWithSingletonContext :: VarName -> StringContext -> NixString
+ Nix.String: mkNixStringWithoutContext :: Text -> NixString
+ Nix.TH: extQOnFreeVars :: (Typeable b, Typeable loc) => (Set VarName -> loc -> Maybe q) -> NExpr -> b -> Maybe q
+ Nix.TH: instance Nix.TH.ToExpr GHC.Num.Integer.Integer
+ Nix.TH: parseExpr :: MonadFail m => Text -> m NExpr
+ Nix.Type.Infer: instance GHC.Base.Monoid Nix.Type.Infer.InferState
+ Nix.Type.Infer: instance GHC.Base.Semigroup Nix.Type.Infer.InferState
+ Nix.Type.Infer: instance GHC.Classes.Eq Nix.Type.Infer.InferState
+ Nix.Type.Infer: instance GHC.Classes.Ord Nix.Type.Infer.InferState
+ Nix.Type.Infer: instance GHC.Enum.Enum Nix.Type.Infer.InferState
+ Nix.Type.Infer: instance GHC.Num.Num Nix.Type.Infer.InferState
+ Nix.Type.Infer: instance Nix.Type.Infer.MonadInfer m => Nix.Convert.FromValue (Nix.Expr.Types.AttrSet (Nix.Type.Infer.Judgment s), Nix.Expr.Types.PositionSet) (Nix.Type.Infer.InferT s m) (Nix.Type.Infer.Judgment s)
+ Nix.Type.Infer: instance Nix.Type.Infer.MonadInfer m => Nix.Convert.ToValue (Nix.Expr.Types.AttrSet (Nix.Type.Infer.Judgment s), Nix.Expr.Types.PositionSet) (Nix.Type.Infer.InferT s m) (Nix.Type.Infer.Judgment s)
+ Nix.Utils: (</>) :: Path -> Path -> Path
+ Nix.Utils: Path :: FilePath -> Path
+ Nix.Utils: addExtension :: Path -> String -> Path
+ Nix.Utils: dropExtensions :: Path -> Path
+ Nix.Utils: infixr 5 </>
+ Nix.Utils: instance Codec.Serialise.Class.Serialise Nix.Utils.Path
+ Nix.Utils: instance Control.DeepSeq.NFData Nix.Utils.Path
+ Nix.Utils: instance Data.Aeson.Types.FromJSON.FromJSON Nix.Utils.Path
+ Nix.Utils: instance Data.Aeson.Types.ToJSON.ToJSON Nix.Utils.Path
+ Nix.Utils: instance Data.Binary.Class.Binary Nix.Utils.Path
+ Nix.Utils: instance Data.Data.Data Nix.Utils.Path
+ Nix.Utils: instance Data.Hashable.Class.Hashable Nix.Utils.Path
+ Nix.Utils: instance Data.String.IsString Nix.Utils.Path
+ Nix.Utils: instance GHC.Base.Monoid Nix.Utils.Path
+ Nix.Utils: instance GHC.Base.Semigroup Nix.Utils.Path
+ Nix.Utils: instance GHC.Classes.Eq Nix.Utils.Path
+ Nix.Utils: instance GHC.Classes.Ord Nix.Utils.Path
+ Nix.Utils: instance GHC.Generics.Generic Nix.Utils.Path
+ Nix.Utils: instance GHC.Read.Read Nix.Utils.Path
+ Nix.Utils: instance GHC.Show.Show Nix.Utils.Path
+ Nix.Utils: instance Relude.String.Conversion.ToText Nix.Utils.Path
+ Nix.Utils: isAbsolute :: Path -> Bool
+ Nix.Utils: joinPath :: [Path] -> Path
+ Nix.Utils: newtype Path
+ Nix.Utils: pass :: Applicative f => f ()
+ Nix.Utils: readFile :: Path -> IO Text
+ Nix.Utils: replaceExtension :: Path -> String -> Path
+ Nix.Utils: splitDirectories :: Path -> [Path]
+ Nix.Utils: takeBaseName :: Path -> String
+ Nix.Utils: takeDirectory :: Path -> Path
+ Nix.Utils: takeExtension :: Path -> String
+ Nix.Utils: takeExtensions :: Path -> String
+ Nix.Utils: takeFileName :: Path -> Path
+ Nix.Utils: traverseM :: (Applicative m, Applicative f, Traversable t) => (a -> m (f b)) -> t a -> m (f (t b))
+ Nix.Utils: type KeyMap = HashMap Text
+ Nix.Utils: whenJust :: Monoid b => (a -> b) -> Maybe a -> b
+ Nix.Utils: whenText :: a -> (Text -> a) -> Text -> a
+ Nix.Value: instance GHC.Base.Monoid Nix.Value.TStringContext
+ Nix.Value: instance GHC.Base.Semigroup Nix.Value.TStringContext
+ Nix.Value: pattern NVPath :: forall {w :: Type -> Type} {t} {m :: Type -> Type} {a}. Comonad w => Path -> Free (NValue' t w m) a
+ Nix.Value: pattern NVSet :: forall {w :: Type -> Type} {t} {m :: Type -> Type} {a}. Comonad w => PositionSet -> AttrSet (Free (NValue' t w m) a) -> Free (NValue' t w m) a
+ Nix.Value: pattern NVBuiltin :: forall {w :: Type -> Type} {t} {m} {a}. Comonad w => VarName -> (NValue t w m -> m (Free (NValue' t w m) a)) -> Free (NValue' t w m) a
+ Prelude: (!!?) :: [a] -> Int -> Maybe a
+ Prelude: ($!!) :: NFData a => (a -> b) -> a -> b
+ Prelude: ($!) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Prelude: ($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
+ Prelude: ($<) :: Contravariant f => f b -> b -> f a
+ Prelude: ($>) :: Functor f => f a -> b -> f b
+ Prelude: (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
+ Prelude: (&&) :: Bool -> Bool -> Bool
+ Prelude: (&&^) :: Monad m => m Bool -> m Bool -> m Bool
+ Prelude: (&) :: a -> (a -> b) -> b
+ Prelude: (*) :: Num a => a -> a -> a
+ Prelude: (**) :: Floating a => a -> a -> a
+ Prelude: (*>) :: Applicative f => f a -> f b -> f b
+ Prelude: (+) :: Num a => a -> a -> a
+ Prelude: (++) :: [a] -> [a] -> [a]
+ Prelude: (-) :: Num a => a -> a -> a
+ Prelude: (.) :: (b -> c) -> (a -> b) -> a -> c
+ Prelude: (/) :: Fractional a => a -> a -> a
+ Prelude: (/=) :: Eq a => a -> a -> Bool
+ Prelude: (:|) :: a -> [a] -> NonEmpty a
+ Prelude: (<$!>) :: Monad m => (a -> b) -> m a -> m b
+ Prelude: (<$) :: Functor f => a -> f b -> f a
+ Prelude: (<$>) :: Functor f => (a -> b) -> f a -> f b
+ Prelude: (<&>) :: Functor f => f a -> (a -> b) -> f b
+ Prelude: (<) :: Ord a => a -> a -> Bool
+ Prelude: (<*) :: Applicative f => f a -> f b -> f a
+ Prelude: (<**>) :: Applicative f => f a -> f (a -> b) -> f b
+ Prelude: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
+ Prelude: (<<$>>) :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b)
+ Prelude: (<<<) :: forall {k} cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ Prelude: (<=) :: Ord a => a -> a -> Bool
+ Prelude: (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
+ Prelude: (<>) :: Semigroup a => a -> a -> a
+ Prelude: (<|>) :: Alternative f => f a -> f a -> f a
+ Prelude: (=<<) :: Monad m => (a -> m b) -> m a -> m b
+ Prelude: (==) :: Eq a => a -> a -> Bool
+ Prelude: (>$$<) :: Contravariant f => f b -> (a -> b) -> f a
+ Prelude: (>$) :: Contravariant f => b -> f b -> f a
+ Prelude: (>$<) :: Contravariant f => (a -> b) -> f b -> f a
+ Prelude: (>) :: Ord a => a -> a -> Bool
+ Prelude: (>=) :: Ord a => a -> a -> Bool
+ Prelude: (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
+ Prelude: (>>) :: Monad m => m a -> m b -> m b
+ Prelude: (>>=) :: Monad m => m a -> (a -> m b) -> m b
+ Prelude: (>>>) :: forall {k} cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ Prelude: (?:) :: Maybe a -> a -> a
+ Prelude: (??) :: Functor f => f (a -> b) -> a -> f b
+ Prelude: (^) :: (Num a, Integral b) => a -> b -> a
+ Prelude: (^^) :: (Fractional a, Integral b) => a -> b -> a
+ Prelude: (||) :: Bool -> Bool -> Bool
+ Prelude: (||^) :: Monad m => m Bool -> m Bool -> m Bool
+ Prelude: -- | Type of a single element of the structure.
+ Prelude: All :: Bool -> All
+ Prelude: Alt :: f a -> Alt (f :: k -> Type) (a :: k)
+ Prelude: Any :: Bool -> Any
+ Prelude: Ap :: f a -> Ap (f :: k -> Type) (a :: k)
+ Prelude: AppendMode :: IOMode
+ Prelude: BlockBuffering :: Maybe Int -> BufferMode
+ Prelude: Bug :: SomeException -> CallStack -> Bug
+ Prelude: Comparison :: (a -> a -> Ordering) -> Comparison a
+ Prelude: Compose :: f (g a) -> Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1)
+ Prelude: Const :: a -> Const a (b :: k)
+ Prelude: D# :: Double# -> Double
+ Prelude: Down :: a -> Down a
+ Prelude: Dual :: a -> Dual a
+ Prelude: EQ :: Ordering
+ Prelude: Endo :: (a -> a) -> Endo a
+ Prelude: Equivalence :: (a -> a -> Bool) -> Equivalence a
+ Prelude: ExceptT :: m (Either e a) -> ExceptT e (m :: Type -> Type) a
+ Prelude: F# :: Float# -> Float
+ Prelude: False :: Bool
+ Prelude: First :: Maybe a -> First a
+ Prelude: GT :: Ordering
+ Prelude: Identity :: a -> Identity a
+ Prelude: Just :: a -> Maybe a
+ Prelude: LT :: Ordering
+ Prelude: Last :: Maybe a -> Last a
+ Prelude: Left :: a -> Either a b
+ Prelude: LineBuffering :: BufferMode
+ Prelude: MaybeT :: m (Maybe a) -> MaybeT (m :: Type -> Type) a
+ Prelude: NoBuffering :: BufferMode
+ Prelude: Nothing :: Maybe a
+ Prelude: Op :: (b -> a) -> Op a b
+ Prelude: Option :: Maybe a -> Option a
+ Prelude: Predicate :: (a -> Bool) -> Predicate a
+ Prelude: Product :: a -> Product a
+ Prelude: Proxy :: Proxy (t :: k)
+ Prelude: ReadMode :: IOMode
+ Prelude: ReadWriteMode :: IOMode
+ Prelude: ReaderT :: (r -> m a) -> ReaderT r (m :: Type -> Type) a
+ Prelude: Right :: b -> Either a b
+ Prelude: SomeException :: e -> SomeException
+ Prelude: SomeNat :: Proxy n -> SomeNat
+ Prelude: StateT :: (s -> m (a, s)) -> StateT s (m :: Type -> Type) a
+ Prelude: Sum :: a -> Sum a
+ Prelude: True :: Bool
+ Prelude: Undefined :: Undefined
+ Prelude: WriteMode :: IOMode
+ Prelude: ZipList :: [a] -> ZipList a
+ Prelude: [appEndo] :: Endo a -> a -> a
+ Prelude: [getAll] :: All -> Bool
+ Prelude: [getAlt] :: Alt (f :: k -> Type) (a :: k) -> f a
+ Prelude: [getAny] :: Any -> Bool
+ Prelude: [getAp] :: Ap (f :: k -> Type) (a :: k) -> f a
+ Prelude: [getComparison] :: Comparison a -> a -> a -> Ordering
+ Prelude: [getCompose] :: Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1) -> f (g a)
+ Prelude: [getConst] :: Const a (b :: k) -> a
+ Prelude: [getDown] :: Down a -> a
+ Prelude: [getDual] :: Dual a -> a
+ Prelude: [getEquivalence] :: Equivalence a -> a -> a -> Bool
+ Prelude: [getFirst] :: First a -> Maybe a
+ Prelude: [getLast] :: Last a -> Maybe a
+ Prelude: [getOp] :: Op a b -> b -> a
+ Prelude: [getOption] :: Option a -> Maybe a
+ Prelude: [getPredicate] :: Predicate a -> a -> Bool
+ Prelude: [getProduct] :: Product a -> a
+ Prelude: [getSum] :: Sum a -> a
+ Prelude: [getZipList] :: ZipList a -> [a]
+ Prelude: [runIdentity] :: Identity a -> a
+ Prelude: [runMaybeT] :: MaybeT (m :: Type -> Type) a -> m (Maybe a)
+ Prelude: [runReaderT] :: ReaderT r (m :: Type -> Type) a -> r -> m a
+ Prelude: [runStateT] :: StateT s (m :: Type -> Type) a -> s -> m (a, s)
+ Prelude: abs :: Num a => a -> a
+ Prelude: absurd :: Void -> a
+ Prelude: acos :: Floating a => a -> a
+ Prelude: acosh :: Floating a => a -> a
+ Prelude: all :: Foldable t => (a -> Bool) -> t a -> Bool
+ Prelude: allM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
+ Prelude: and :: Foldable t => t Bool -> Bool
+ Prelude: andM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
+ Prelude: any :: Foldable t => (a -> Bool) -> t a -> Bool
+ Prelude: anyM :: (Foldable f, Monad m) => (a -> m Bool) -> f a -> m Bool
+ Prelude: appendFile :: MonadIO m => FilePath -> String -> m ()
+ Prelude: appendFileBS :: MonadIO m => FilePath -> ByteString -> m ()
+ Prelude: appendFileLBS :: MonadIO m => FilePath -> LByteString -> m ()
+ Prelude: appendFileLText :: MonadIO m => FilePath -> LText -> m ()
+ Prelude: appendFileText :: MonadIO m => FilePath -> Text -> m ()
+ Prelude: appliedTo :: Applicative f => f a -> f (a -> b) -> f b
+ Prelude: asTypeOf :: a -> a -> a
+ Prelude: asin :: Floating a => a -> a
+ Prelude: asinh :: Floating a => a -> a
+ Prelude: ask :: MonadReader r m => m r
+ Prelude: asks :: MonadReader r m => (r -> a) -> m a
+ Prelude: asum :: (Foldable t, Alternative f) => t (f a) -> f a
+ Prelude: asumMap :: forall b m f a. (Foldable f, Alternative m) => (a -> m b) -> f a -> m b
+ Prelude: atan :: Floating a => a -> a
+ Prelude: atan2 :: RealFloat a => a -> a -> a
+ Prelude: atanh :: Floating a => a -> a
+ Prelude: atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Prelude: atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
+ Prelude: atomicModifyIORef'_ :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Prelude: atomicModifyIORef_ :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Prelude: atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()
+ Prelude: atomically :: MonadIO m => STM a -> m a
+ Prelude: biList :: Bifoldable t => t a a -> [a]
+ Prelude: biall :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
+ Prelude: biand :: Bifoldable t => t Bool Bool -> Bool
+ Prelude: biany :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
+ Prelude: biasum :: (Bifoldable t, Alternative f) => t (f a) (f a) -> f a
+ Prelude: bielem :: (Bifoldable t, Eq a) => a -> t a a -> Bool
+ Prelude: bifind :: Bifoldable t => (a -> Bool) -> t a a -> Maybe a
+ Prelude: bifold :: (Bifoldable p, Monoid m) => p m m -> m
+ Prelude: bifoldMap :: (Bifoldable p, Monoid m) => (a -> m) -> (b -> m) -> p a b -> m
+ Prelude: bifoldMapDefault :: (Bitraversable t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m
+ Prelude: bifoldl :: Bifoldable p => (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c
+ Prelude: bifoldl' :: Bifoldable t => (a -> b -> a) -> (a -> c -> a) -> a -> t b c -> a
+ Prelude: bifoldlM :: (Bifoldable t, Monad m) => (a -> b -> m a) -> (a -> c -> m a) -> a -> t b c -> m a
+ Prelude: bifoldr :: Bifoldable p => (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c
+ Prelude: bifoldr' :: Bifoldable t => (a -> c -> c) -> (b -> c -> c) -> c -> t a b -> c
+ Prelude: bifoldrM :: (Bifoldable t, Monad m) => (a -> c -> m c) -> (b -> c -> m c) -> c -> t a b -> m c
+ Prelude: bifor :: (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d)
+ Prelude: bifor_ :: (Bifoldable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f ()
+ Prelude: bilength :: Bifoldable t => t a b -> Int
+ Prelude: bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
+ Prelude: bimapDefault :: Bitraversable t => (a -> b) -> (c -> d) -> t a c -> t b d
+ Prelude: binull :: Bifoldable t => t a b -> Bool
+ Prelude: bior :: Bifoldable t => t Bool Bool -> Bool
+ Prelude: bisequence :: (Bitraversable t, Applicative f) => t (f a) (f b) -> f (t a b)
+ Prelude: bisequence_ :: (Bifoldable t, Applicative f) => t (f a) (f b) -> f ()
+ Prelude: bitraverse :: (Bitraversable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
+ Prelude: bitraverse_ :: (Bifoldable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f ()
+ Prelude: bool :: a -> a -> Bool -> a
+ Prelude: boundedEnumFrom :: (Enum a, Bounded a) => a -> [a]
+ Prelude: boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a]
+ Prelude: break :: (a -> Bool) -> [a] -> ([a], [a])
+ Prelude: bug :: (HasCallStack, Exception e) => e -> a
+ Prelude: byteSwap16 :: Word16 -> Word16
+ Prelude: byteSwap32 :: Word32 -> Word32
+ Prelude: byteSwap64 :: Word64 -> Word64
+ Prelude: callStack :: HasCallStack => CallStack
+ Prelude: catMaybes :: [Maybe a] -> [a]
+ Prelude: catchSTM :: Exception e => STM a -> (e -> STM a) -> STM a
+ Prelude: ceiling :: (RealFrac a, Integral b) => a -> b
+ Prelude: chainedTo :: Monad m => (a -> m b) -> m a -> m b
+ Prelude: chr :: Int -> Char
+ Prelude: class Applicative f => Alternative (f :: Type -> Type)
+ Prelude: class Functor f => Applicative (f :: Type -> Type)
+ Prelude: class Bifoldable (p :: Type -> Type -> Type)
+ Prelude: class Bifunctor (p :: Type -> Type -> Type)
+ Prelude: class (Bifunctor t, Bifoldable t) => Bitraversable (t :: Type -> Type -> Type)
+ Prelude: class Bounded a
+ Prelude: class a ~R# b => Coercible (a :: k) (b :: k)
+ Prelude: class Contravariant (f :: Type -> Type)
+ Prelude: class ConvertUtf8 a b
+ Prelude: class Enum a
+ Prelude: class Eq a
+ Prelude: class (Typeable e, Show e) => Exception e
+ Prelude: class Fractional a => Floating a
+ Prelude: class Foldable (t :: Type -> Type)
+ Prelude: class Num a => Fractional a
+ Prelude: class Functor (f :: Type -> Type)
+ Prelude: class Generic a
+ Prelude: class Hashable a
+ Prelude: class (Real a, Enum a) => Integral a
+ Prelude: class IsLabel (x :: Symbol) a
+ Prelude: class IsList l
+ Prelude: class IsString a
+ Prelude: class KnownNat (n :: Nat)
+ Prelude: class LazyStrict l s | l -> s, s -> l
+ Prelude: class Applicative m => Monad (m :: Type -> Type)
+ Prelude: class Monad m => MonadFail (m :: Type -> Type)
+ Prelude: class Monad m => MonadIO (m :: Type -> Type)
+ Prelude: class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type)
+ Prelude: class Monad m => MonadReader r (m :: Type -> Type) | m -> r
+ Prelude: class Monad m => MonadState s (m :: Type -> Type) | m -> s
+ Prelude: class MonadTrans (t :: Type -> Type -> Type -> Type)
+ Prelude: class Semigroup a => Monoid a
+ Prelude: class NFData a
+ Prelude: class Num a
+ Prelude: class One x where {
+ Prelude: class Eq a => Ord a
+ Prelude: class Read a
+ Prelude: class (Num a, Ord a) => Real a
+ Prelude: class (RealFrac a, Floating a) => RealFloat a
+ Prelude: class (Real a, Fractional a) => RealFrac a
+ Prelude: class Semigroup a
+ Prelude: class Show a
+ Prelude: class ToLText a
+ Prelude: class ToString a
+ Prelude: class ToText a
+ Prelude: class (Functor t, Foldable t) => Traversable (t :: Type -> Type)
+ Prelude: class Typeable (a :: k)
+ Prelude: coerce :: forall {k :: RuntimeRep} (a :: TYPE k) (b :: TYPE k). Coercible a b => a -> b
+ Prelude: compare :: Ord a => a -> a -> Ordering
+ Prelude: comparing :: Ord a => (b -> a) -> b -> b -> Ordering
+ Prelude: comparisonEquivalence :: Comparison a -> Equivalence a
+ Prelude: concat :: Foldable t => t [a] -> [a]
+ Prelude: concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
+ Prelude: const :: a -> b -> a
+ Prelude: contramap :: Contravariant f => (a' -> a) -> f a -> f a'
+ Prelude: cos :: Floating a => a -> a
+ Prelude: cosh :: Floating a => a -> a
+ Prelude: currentCallStack :: IO [String]
+ Prelude: curry :: ((a, b) -> c) -> a -> b -> c
+ Prelude: cycle :: [a] -> [a]
+ Prelude: cycle1 :: Semigroup m => m -> m
+ Prelude: data Bool
+ Prelude: data BufferMode
+ Prelude: data Bug
+ Prelude: data ByteString
+ Prelude: data CallStack
+ Prelude: data Char
+ Prelude: data Constraint
+ Prelude: data Double
+ Prelude: data Either a b
+ Prelude: data Float
+ Prelude: data Handle
+ Prelude: data HashMap k v
+ Prelude: data HashSet a
+ Prelude: data IO a
+ Prelude: data IOMode
+ Prelude: data IORef a
+ Prelude: data IdentityT (f :: k -> Type) (a :: k)
+ Prelude: data Int
+ Prelude: data Int16
+ Prelude: data Int32
+ Prelude: data Int64
+ Prelude: data Int8
+ Prelude: data IntMap a
+ Prelude: data IntSet
+ Prelude: data Integer
+ Prelude: data MVar a
+ Prelude: data Map k a
+ Prelude: data Maybe a
+ Prelude: data Nat
+ Prelude: data Natural
+ Prelude: data NonEmpty a
+ Prelude: data Ordering
+ Prelude: data Proxy (t :: k)
+ Prelude: data Ratio a
+ Prelude: data STM a
+ Prelude: data Seq a
+ Prelude: data Set a
+ Prelude: data ShortByteString
+ Prelude: data SomeException
+ Prelude: data SomeNat
+ Prelude: data TMVar a
+ Prelude: data TVar a
+ Prelude: data Text
+ Prelude: data Undefined
+ Prelude: data UnicodeException
+ Prelude: data Void
+ Prelude: data Word
+ Prelude: data Word16
+ Prelude: data Word32
+ Prelude: data Word64
+ Prelude: data Word8
+ Prelude: data WrappedMonoid m
+ Prelude: decodeFloat :: RealFloat a => a -> (Integer, Int)
+ Prelude: decodeUtf8 :: ConvertUtf8 a b => b -> a
+ Prelude: decodeUtf8' :: ByteString -> Either UnicodeException Text
+ Prelude: decodeUtf8Strict :: ConvertUtf8 a b => b -> Either UnicodeException a
+ Prelude: decodeUtf8With :: OnDecodeError -> ByteString -> Text
+ Prelude: deepseq :: NFData a => a -> b -> b
+ Prelude: defaultComparison :: Ord a => Comparison a
+ Prelude: defaultEquivalence :: Eq a => Equivalence a
+ Prelude: denominator :: Ratio a -> a
+ Prelude: die :: MonadIO m => String -> m a
+ Prelude: displayException :: Exception e => e -> String
+ Prelude: div :: Integral a => a -> a -> a
+ Prelude: divMod :: Integral a => a -> a -> (a, a)
+ Prelude: drop :: Int -> [a] -> [a]
+ Prelude: dropWhile :: (a -> Bool) -> [a] -> [a]
+ Prelude: either :: (a -> c) -> (b -> c) -> Either a b -> c
+ Prelude: elem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool
+ Prelude: empty :: Alternative f => f a
+ Prelude: encodeFloat :: RealFloat a => Integer -> Int -> a
+ Prelude: encodeUtf8 :: ConvertUtf8 a b => a -> b
+ Prelude: enumFrom :: Enum a => a -> [a]
+ Prelude: enumFromThen :: Enum a => a -> a -> [a]
+ Prelude: enumFromThenTo :: Enum a => a -> a -> a -> [a]
+ Prelude: enumFromTo :: Enum a => a -> a -> [a]
+ Prelude: error :: forall (r :: RuntimeRep) (a :: TYPE r) t. (HasCallStack, IsText t) => t -> a
+ Prelude: etaReaderT :: forall r (m :: Type -> Type) a. ReaderT r m a -> ReaderT r m a
+ Prelude: evalState :: State s a -> s -> a
+ Prelude: evalStateT :: Monad m => StateT s m a -> s -> m a
+ Prelude: evaluateNF :: (NFData a, MonadIO m) => a -> m a
+ Prelude: evaluateNF_ :: (NFData a, MonadIO m) => a -> m ()
+ Prelude: evaluateWHNF :: MonadIO m => a -> m a
+ Prelude: evaluateWHNF_ :: MonadIO m => a -> m ()
+ Prelude: evaluatingState :: s -> State s a -> a
+ Prelude: evaluatingStateT :: Functor f => s -> StateT s f a -> f a
+ Prelude: even :: Integral a => a -> Bool
+ Prelude: exceptToMaybeT :: forall (m :: Type -> Type) e a. Functor m => ExceptT e m a -> MaybeT m a
+ Prelude: execState :: State s a -> s -> s
+ Prelude: execStateT :: Monad m => StateT s m a -> s -> m s
+ Prelude: executingState :: s -> State s a -> s
+ Prelude: executingStateT :: Functor f => s -> StateT s f a -> f s
+ Prelude: exitFailure :: MonadIO m => m a
+ Prelude: exitSuccess :: MonadIO m => m a
+ Prelude: exitWith :: MonadIO m => ExitCode -> m a
+ Prelude: exp :: Floating a => a -> a
+ Prelude: fail :: MonadFail m => String -> m a
+ Prelude: filter :: (a -> Bool) -> [a] -> [a]
+ Prelude: filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
+ Prelude: find :: Foldable t => (a -> Bool) -> t a -> Maybe a
+ Prelude: first :: Bifunctor p => (a -> b) -> p a c -> p b c
+ Prelude: fix :: (a -> a) -> a
+ Prelude: flap :: Functor f => f (a -> b) -> a -> f b
+ Prelude: flip :: (a -> b -> c) -> b -> a -> c
+ Prelude: flipfoldl' :: Foldable f => (a -> b -> b) -> b -> f a -> b
+ Prelude: floatDigits :: RealFloat a => a -> Int
+ Prelude: floatRadix :: RealFloat a => a -> Integer
+ Prelude: floatRange :: RealFloat a => a -> (Int, Int)
+ Prelude: floor :: (RealFrac a, Integral b) => a -> b
+ Prelude: fmap :: Functor f => (a -> b) -> f a -> f b
+ Prelude: fold :: (Foldable t, Monoid m) => t m -> m
+ Prelude: foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Prelude: foldMap' :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Prelude: foldMapA :: (Semigroup b, Monoid b, Applicative m, Foldable f) => (a -> m b) -> f a -> m b
+ Prelude: foldMapM :: (Monoid b, Monad m, Foldable f) => (a -> m b) -> f a -> m b
+ Prelude: foldl' :: Foldable t => (b -> a -> b) -> b -> t a -> b
+ Prelude: foldlM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
+ Prelude: foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
+ Prelude: forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
+ Prelude: forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
+ Prelude: for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()
+ Prelude: forever :: Applicative f => f a -> f b
+ Prelude: fromEnum :: Enum a => a -> Int
+ Prelude: fromException :: Exception e => SomeException -> Maybe e
+ Prelude: fromInteger :: Num a => Integer -> a
+ Prelude: fromIntegral :: (Integral a, Num b) => a -> b
+ Prelude: fromLabel :: IsLabel x a => a
+ Prelude: fromLazy :: LazyStrict l s => l -> s
+ Prelude: fromLeft :: a -> Either a b -> a
+ Prelude: fromList :: IsList l => [Item l] -> l
+ Prelude: fromListN :: IsList l => Int -> [Item l] -> l
+ Prelude: fromMaybe :: a -> Maybe a -> a
+ Prelude: fromRational :: Fractional a => Rational -> a
+ Prelude: fromRight :: b -> Either a b -> b
+ Prelude: fromShort :: ShortByteString -> ByteString
+ Prelude: fromStrict :: LazyStrict l s => s -> l
+ Prelude: fromString :: IsString a => String -> a
+ Prelude: fst :: (a, b) -> a
+ Prelude: gcd :: Integral a => a -> a -> a
+ Prelude: genericDrop :: Integral i => i -> [a] -> [a]
+ Prelude: genericLength :: Num i => [a] -> i
+ Prelude: genericReplicate :: Integral i => i -> a -> [a]
+ Prelude: genericSplitAt :: Integral i => i -> [a] -> ([a], [a])
+ Prelude: genericTake :: Integral i => i -> [a] -> [a]
+ Prelude: get :: MonadState s m => m s
+ Prelude: getArgs :: MonadIO m => m [String]
+ Prelude: getCallStack :: CallStack -> [([Char], SrcLoc)]
+ Prelude: getLine :: MonadIO m => m Text
+ Prelude: getStackTrace :: IO (Maybe [Location])
+ Prelude: gets :: MonadState s m => (s -> a) -> m a
+ Prelude: group :: Eq a => [a] -> [[a]]
+ Prelude: guard :: Alternative f => Bool -> f ()
+ Prelude: guardM :: MonadPlus m => m Bool -> m ()
+ Prelude: guarded :: Alternative f => (a -> Bool) -> a -> f a
+ Prelude: hFlush :: MonadIO m => Handle -> m ()
+ Prelude: hGetBuffering :: MonadIO m => Handle -> m BufferMode
+ Prelude: hIsEOF :: MonadIO m => Handle -> m Bool
+ Prelude: hSetBuffering :: MonadIO m => Handle -> BufferMode -> m ()
+ Prelude: hashNub :: (Eq a, Hashable a) => [a] -> [a]
+ Prelude: hashWithSalt :: Hashable a => Int -> a -> Int
+ Prelude: head :: IsNonEmpty f a a "head" => f a -> a
+ Prelude: hoistEither :: forall (m :: Type -> Type) e a. Applicative m => Either e a -> ExceptT e m a
+ Prelude: hoistMaybe :: forall (m :: Type -> Type) a. Applicative m => Maybe a -> MaybeT m a
+ Prelude: id :: a -> a
+ Prelude: identity :: a -> a
+ Prelude: ifM :: Monad m => m Bool -> m a -> m a -> m a
+ Prelude: infinitely :: Applicative f => f a -> f Void
+ Prelude: infix 4 >=
+ Prelude: infix 9 !!?
+ Prelude: infixl 0 `on`
+ Prelude: infixl 1 <&>
+ Prelude: infixl 3 <|>
+ Prelude: infixl 4 <<$>>
+ Prelude: infixl 6 `xor`
+ Prelude: infixl 7 *
+ Prelude: infixr 0 ?:
+ Prelude: infixr 1 =<<
+ Prelude: infixr 2 ||
+ Prelude: infixr 3 &&
+ Prelude: infixr 5 :|
+ Prelude: infixr 6 <>
+ Prelude: infixr 8 ^
+ Prelude: infixr 9 `Compose`
+ Prelude: init :: IsNonEmpty f a [a] "init" => f a -> [a]
+ Prelude: inits :: [a] -> [[a]]
+ Prelude: intNub :: [Int] -> [Int]
+ Prelude: intNubOn :: (a -> Int) -> [a] -> [a]
+ Prelude: integerToBounded :: (Integral a, Bounded a) => Integer -> Maybe a
+ Prelude: integerToNatural :: Integer -> Maybe Natural
+ Prelude: intercalate :: [a] -> [[a]] -> [a]
+ Prelude: intersperse :: a -> [a] -> [a]
+ Prelude: inverseMap :: (Bounded a, Enum a, Ord k) => (a -> k) -> k -> Maybe a
+ Prelude: isDenormalized :: RealFloat a => a -> Bool
+ Prelude: isEmptyTMVar :: TMVar a -> STM Bool
+ Prelude: isIEEE :: RealFloat a => a -> Bool
+ Prelude: isInfinite :: RealFloat a => a -> Bool
+ Prelude: isJust :: Maybe a -> Bool
+ Prelude: isLeft :: Either a b -> Bool
+ Prelude: isNaN :: RealFloat a => a -> Bool
+ Prelude: isNegativeZero :: RealFloat a => a -> Bool
+ Prelude: isNothing :: Maybe a -> Bool
+ Prelude: isPrefixOf :: Eq a => [a] -> [a] -> Bool
+ Prelude: isRight :: Either a b -> Bool
+ Prelude: iterate :: (a -> a) -> a -> [a]
+ Prelude: join :: Monad m => m (m a) -> m a
+ Prelude: last :: IsNonEmpty f a a "last" => f a -> a
+ Prelude: lcm :: Integral a => a -> a -> a
+ Prelude: leftToMaybe :: Either l r -> Maybe l
+ Prelude: lefts :: [Either a b] -> [a]
+ Prelude: length :: Foldable t => t a -> Int
+ Prelude: lenientDecode :: OnDecodeError
+ Prelude: lift :: (MonadTrans t, Monad m) => m a -> t m a
+ Prelude: liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
+ Prelude: liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
+ Prelude: liftIO :: MonadIO m => IO a -> m a
+ Prelude: lines :: IsText t "lines" => t -> [t]
+ Prelude: listToMaybe :: [a] -> Maybe a
+ Prelude: local :: MonadReader r m => (r -> r) -> m a -> m a
+ Prelude: logBase :: Floating a => a -> a -> a
+ Prelude: lookupEnv :: MonadIO m => String -> m (Maybe String)
+ Prelude: many :: Alternative f => f a -> f [a]
+ Prelude: map :: (a -> b) -> [a] -> [b]
+ Prelude: mapAccumL :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)
+ Prelude: mapAccumR :: Traversable t => (a -> b -> (a, c)) -> a -> t b -> (a, t c)
+ Prelude: mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c])
+ Prelude: mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
+ Prelude: mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
+ Prelude: mapMaybe :: (a -> Maybe b) -> [a] -> [b]
+ Prelude: mapMaybeM :: Monad m => (a -> m (Maybe b)) -> [a] -> m [b]
+ Prelude: mappend :: Monoid a => a -> a -> a
+ Prelude: max :: Ord a => a -> a -> a
+ Prelude: maxBound :: Bounded a => a
+ Prelude: maxInt :: Int
+ Prelude: maybe :: b -> (a -> b) -> Maybe a -> b
+ Prelude: maybeAt :: Int -> [a] -> Maybe a
+ Prelude: maybeToExceptT :: forall (m :: Type -> Type) e a. Functor m => e -> MaybeT m a -> ExceptT e m a
+ Prelude: maybeToLeft :: r -> Maybe l -> Either l r
+ Prelude: maybeToList :: Maybe a -> [a]
+ Prelude: maybeToMonoid :: Monoid m => Maybe m -> m
+ Prelude: maybeToRight :: l -> Maybe r -> Either l r
+ Prelude: mconcat :: Monoid a => [a] -> a
+ Prelude: mempty :: Monoid a => a
+ Prelude: memptyIfFalse :: Monoid m => Bool -> m -> m
+ Prelude: memptyIfTrue :: Monoid m => Bool -> m -> m
+ Prelude: mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
+ Prelude: min :: Ord a => a -> a -> a
+ Prelude: minBound :: Bounded a => a
+ Prelude: minInt :: Int
+ Prelude: mkWeakTMVar :: TMVar a -> IO () -> IO (Weak (TMVar a))
+ Prelude: mod :: Integral a => a -> a -> a
+ Prelude: modify :: MonadState s m => (s -> s) -> m ()
+ Prelude: modify' :: MonadState s m => (s -> s) -> m ()
+ Prelude: modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Prelude: modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()
+ Prelude: modifyTVar' :: TVar a -> (a -> a) -> STM ()
+ Prelude: mplus :: MonadPlus m => m a -> m a -> m a
+ Prelude: mtimesDefault :: (Integral b, Monoid a) => b -> a -> a
+ Prelude: mzero :: MonadPlus m => m a
+ Prelude: natVal :: forall (n :: Nat) proxy. KnownNat n => proxy n -> Natural
+ Prelude: negate :: Num a => a -> a
+ Prelude: newEmptyMVar :: MonadIO m => m (MVar a)
+ Prelude: newEmptyTMVar :: STM (TMVar a)
+ Prelude: newEmptyTMVarIO :: MonadIO m => m (TMVar a)
+ Prelude: newIORef :: MonadIO m => a -> m (IORef a)
+ Prelude: newMVar :: MonadIO m => a -> m (MVar a)
+ Prelude: newTMVar :: a -> STM (TMVar a)
+ Prelude: newTMVarIO :: MonadIO m => a -> m (TMVar a)
+ Prelude: newTVar :: a -> STM (TVar a)
+ Prelude: newTVarIO :: MonadIO m => a -> m (TVar a)
+ Prelude: newtype All
+ Prelude: newtype Alt (f :: k -> Type) (a :: k)
+ Prelude: newtype Any
+ Prelude: newtype Ap (f :: k -> Type) (a :: k)
+ Prelude: newtype Comparison a
+ Prelude: newtype Compose (f :: k -> Type) (g :: k1 -> k) (a :: k1)
+ Prelude: newtype Const a (b :: k)
+ Prelude: newtype Down a
+ Prelude: newtype Dual a
+ Prelude: newtype Endo a
+ Prelude: newtype Equivalence a
+ Prelude: newtype ExceptT e (m :: Type -> Type) a
+ Prelude: newtype First a
+ Prelude: newtype Identity a
+ Prelude: newtype Last a
+ Prelude: newtype MaybeT (m :: Type -> Type) a
+ Prelude: newtype Op a b
+ Prelude: newtype Option a
+ Prelude: newtype Predicate a
+ Prelude: newtype Product a
+ Prelude: newtype ReaderT r (m :: Type -> Type) a
+ Prelude: newtype StateT s (m :: Type -> Type) a
+ Prelude: newtype Sum a
+ Prelude: newtype ZipList a
+ Prelude: nonEmpty :: [a] -> Maybe (NonEmpty a)
+ Prelude: not :: Bool -> Bool
+ Prelude: notElem :: (Foldable f, DisallowElem f, Eq a) => a -> f a -> Bool
+ Prelude: null :: Foldable t => t a -> Bool
+ Prelude: numerator :: Ratio a -> a
+ Prelude: odd :: Integral a => a -> Bool
+ Prelude: on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
+ Prelude: one :: One x => OneItem x -> x
+ Prelude: optional :: Alternative f => f a -> f (Maybe a)
+ Prelude: or :: Foldable t => t Bool -> Bool
+ Prelude: orM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
+ Prelude: ord :: Char -> Int
+ Prelude: ordNub :: Ord a => [a] -> [a]
+ Prelude: ordNubOn :: Ord b => (a -> b) -> [a] -> [a]
+ Prelude: otherwise :: Bool
+ Prelude: partitionEithers :: [Either a b] -> ([a], [b])
+ Prelude: partitionWith :: (a -> Either b c) -> [a] -> ([b], [c])
+ Prelude: pattern Exc :: Exception e => e -> SomeException
+ Prelude: permutations :: [a] -> [[a]]
+ Prelude: phantom :: (Functor f, Contravariant f) => f a -> f b
+ Prelude: pi :: Floating a => a
+ Prelude: pred :: Enum a => a -> a
+ Prelude: prettyCallStack :: CallStack -> String
+ Prelude: prettySrcLoc :: SrcLoc -> String
+ Prelude: print :: forall a m. (MonadIO m, Show a) => a -> m ()
+ Prelude: product :: forall a f. (Foldable f, Num a) => f a -> a
+ Prelude: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
+ Prelude: pure :: Applicative f => a -> f a
+ Prelude: put :: MonadState s m => s -> m ()
+ Prelude: putBS :: MonadIO m => ByteString -> m ()
+ Prelude: putBSLn :: MonadIO m => ByteString -> m ()
+ Prelude: putLBS :: MonadIO m => LByteString -> m ()
+ Prelude: putLBSLn :: MonadIO m => LByteString -> m ()
+ Prelude: putLText :: MonadIO m => LText -> m ()
+ Prelude: putLTextLn :: MonadIO m => LText -> m ()
+ Prelude: putMVar :: MonadIO m => MVar a -> a -> m ()
+ Prelude: putStr :: MonadIO m => String -> m ()
+ Prelude: putStrLn :: MonadIO m => String -> m ()
+ Prelude: putTMVar :: TMVar a -> a -> STM ()
+ Prelude: putText :: MonadIO m => Text -> m ()
+ Prelude: putTextLn :: MonadIO m => Text -> m ()
+ Prelude: quot :: Integral a => a -> a -> a
+ Prelude: quotRem :: Integral a => a -> a -> (a, a)
+ Prelude: readEither :: Read a => String -> Either Text a
+ Prelude: readFile' :: MonadIO m => FilePath -> m String
+ Prelude: readFileBS :: MonadIO m => FilePath -> m ByteString
+ Prelude: readFileLBS :: MonadIO m => FilePath -> m LByteString
+ Prelude: readFileLText :: MonadIO m => FilePath -> m LText
+ Prelude: readFileText :: MonadIO m => FilePath -> m Text
+ Prelude: readIORef :: MonadIO m => IORef a -> m a
+ Prelude: readMVar :: MonadIO m => MVar a -> m a
+ Prelude: readMaybe :: Read a => String -> Maybe a
+ Prelude: readTMVar :: TMVar a -> STM a
+ Prelude: readTVar :: TVar a -> STM a
+ Prelude: readTVarIO :: MonadIO m => TVar a -> m a
+ Prelude: reader :: MonadReader r m => (r -> a) -> m a
+ Prelude: reads :: Read a => ReadS a
+ Prelude: realToFrac :: (Real a, Fractional b) => a -> b
+ Prelude: recip :: Fractional a => a -> a
+ Prelude: rem :: Integral a => a -> a -> a
+ Prelude: repeat :: a -> [a]
+ Prelude: replicate :: Int -> a -> [a]
+ Prelude: replicateM :: Applicative m => Int -> m a -> m [a]
+ Prelude: replicateM_ :: Applicative m => Int -> m a -> m ()
+ Prelude: return :: Monad m => a -> m a
+ Prelude: reverse :: [a] -> [a]
+ Prelude: rightToMaybe :: Either l r -> Maybe r
+ Prelude: rights :: [Either a b] -> [b]
+ Prelude: rnf :: NFData a => a -> ()
+ Prelude: round :: (RealFrac a, Integral b) => a -> b
+ Prelude: runExceptT :: ExceptT e m a -> m (Either e a)
+ Prelude: runReader :: Reader r a -> r -> a
+ Prelude: runState :: State s a -> s -> (a, s)
+ Prelude: scanl :: (b -> a -> b) -> b -> [a] -> [b]
+ Prelude: scanl' :: (b -> a -> b) -> b -> [a] -> [b]
+ Prelude: scanl1 :: (a -> a -> a) -> [a] -> [a]
+ Prelude: scanr :: (a -> b -> b) -> b -> [a] -> [b]
+ Prelude: scanr1 :: (a -> a -> a) -> [a] -> [a]
+ Prelude: sconcat :: Semigroup a => NonEmpty a -> a
+ Prelude: second :: Bifunctor p => (b -> c) -> p a b -> p a c
+ Prelude: seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b
+ Prelude: sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
+ Prelude: sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
+ Prelude: sequenceA_ :: (Foldable t, Applicative f) => t (f a) -> f ()
+ Prelude: sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
+ Prelude: show :: forall b a. (Show a, IsString b) => a -> b
+ Prelude: showStackTrace :: IO (Maybe String)
+ Prelude: signum :: Num a => a -> a
+ Prelude: sin :: Floating a => a -> a
+ Prelude: sinh :: Floating a => a -> a
+ Prelude: snd :: (a, b) -> b
+ Prelude: some :: Alternative f => f a -> f [a]
+ Prelude: someNatVal :: Natural -> SomeNat
+ Prelude: sort :: Ord a => [a] -> [a]
+ Prelude: sortBy :: (a -> a -> Ordering) -> [a] -> [a]
+ Prelude: sortNub :: Ord a => [a] -> [a]
+ Prelude: sortOn :: Ord b => (a -> b) -> [a] -> [a]
+ Prelude: sortWith :: Ord b => (a -> b) -> [a] -> [a]
+ Prelude: span :: (a -> Bool) -> [a] -> ([a], [a])
+ Prelude: splitAt :: Int -> [a] -> ([a], [a])
+ Prelude: sqrt :: Floating a => a -> a
+ Prelude: state :: MonadState s m => (s -> (a, s)) -> m a
+ Prelude: stderr :: Handle
+ Prelude: stdin :: Handle
+ Prelude: stdout :: Handle
+ Prelude: stimes :: (Semigroup a, Integral b) => b -> a -> a
+ Prelude: stimesIdempotent :: Integral b => b -> a -> a
+ Prelude: stimesIdempotentMonoid :: (Integral b, Monoid a) => b -> a -> a
+ Prelude: stimesMonoid :: (Integral b, Monoid a) => b -> a -> a
+ Prelude: strictDecode :: OnDecodeError
+ Prelude: subsequences :: [a] -> [[a]]
+ Prelude: subtract :: Num a => a -> a -> a
+ Prelude: succ :: Enum a => a -> a
+ Prelude: sum :: forall a f. (Foldable f, Num a) => f a -> a
+ Prelude: swap :: (a, b) -> (b, a)
+ Prelude: swapMVar :: MonadIO m => MVar a -> a -> m a
+ Prelude: swapTMVar :: TMVar a -> a -> STM a
+ Prelude: tail :: IsNonEmpty f a [a] "tail" => f a -> [a]
+ Prelude: tails :: [a] -> [[a]]
+ Prelude: take :: Int -> [a] -> [a]
+ Prelude: takeMVar :: MonadIO m => MVar a -> m a
+ Prelude: takeTMVar :: TMVar a -> STM a
+ Prelude: takeWhile :: (a -> Bool) -> [a] -> [a]
+ Prelude: tan :: Floating a => a -> a
+ Prelude: tanh :: Floating a => a -> a
+ Prelude: throwSTM :: Exception e => e -> STM a
+ Prelude: toEnum :: Enum a => Int -> a
+ Prelude: toException :: Exception e => e -> SomeException
+ Prelude: toInteger :: Integral a => a -> Integer
+ Prelude: toIntegralSized :: (Integral a, Integral b, Bits a, Bits b) => a -> Maybe b
+ Prelude: toLText :: ToLText a => a -> LText
+ Prelude: toLazy :: LazyStrict l s => s -> l
+ Prelude: toList :: Foldable t => t a -> [a]
+ Prelude: toRational :: Real a => a -> Rational
+ Prelude: toShort :: ByteString -> ShortByteString
+ Prelude: toStrict :: LazyStrict l s => l -> s
+ Prelude: toString :: ToString a => a -> String
+ Prelude: toText :: ToText a => a -> Text
+ Prelude: traceId :: String -> String
+ Prelude: traceShow :: Show a => a -> b -> b
+ Prelude: traceShowId :: Show a => a -> a
+ Prelude: traceShowM :: (Show a, Applicative f) => a -> f ()
+ Prelude: traceShowWith :: Show b => (a -> b) -> a -> a
+ Prelude: transpose :: [[a]] -> [[a]]
+ Prelude: traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ Prelude: traverse_ :: (Foldable t, Applicative f) => (a -> f b) -> t a -> f ()
+ Prelude: truncate :: (RealFrac a, Integral b) => a -> b
+ Prelude: tryPutMVar :: MonadIO m => MVar a -> a -> m Bool
+ Prelude: tryPutTMVar :: TMVar a -> a -> STM Bool
+ Prelude: tryReadMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Prelude: tryReadTMVar :: TMVar a -> STM (Maybe a)
+ Prelude: tryTakeMVar :: MonadIO m => MVar a -> m (Maybe a)
+ Prelude: tryTakeTMVar :: TMVar a -> STM (Maybe a)
+ Prelude: type FilePath = String
+ Prelude: type HasCallStack = ?callStack :: CallStack
+ Prelude: type LByteString = ByteString
+ Prelude: type LText = Text
+ Prelude: type OnDecodeError = OnError Word8 Char
+ Prelude: type OnError a b = String -> Maybe a -> Maybe b
+ Prelude: type Rational = Ratio Integer
+ Prelude: type Reader r = ReaderT r Identity
+ Prelude: type State s = StateT s Identity
+ Prelude: type String = [Char]
+ Prelude: type Type = Type
+ Prelude: type family OneItem x;
+ Prelude: uncons :: [a] -> Maybe (a, [a])
+ Prelude: uncurry :: (a -> b -> c) -> (a, b) -> c
+ Prelude: undefined :: forall (r :: RuntimeRep) (a :: TYPE r). HasCallStack => a
+ Prelude: unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
+ Prelude: universe :: (Bounded a, Enum a) => [a]
+ Prelude: universeNonEmpty :: (Bounded a, Enum a) => NonEmpty a
+ Prelude: unless :: Applicative f => Bool -> f () -> f ()
+ Prelude: unlessM :: Monad m => m Bool -> m () -> m ()
+ Prelude: unlines :: IsText t "unlines" => [t] -> t
+ Prelude: unstableNub :: (Eq a, Hashable a) => [a] -> [a]
+ Prelude: unwords :: IsText t "unwords" => [t] -> t
+ Prelude: unzip :: [(a, b)] -> ([a], [b])
+ Prelude: unzip3 :: [(a, b, c)] -> ([a], [b], [c])
+ Prelude: usingReader :: r -> Reader r a -> a
+ Prelude: usingReaderT :: r -> ReaderT r m a -> m a
+ Prelude: usingState :: s -> State s a -> (a, s)
+ Prelude: usingStateT :: s -> StateT s m a -> m (a, s)
+ Prelude: vacuous :: Functor f => f Void -> f a
+ Prelude: viaNonEmpty :: (NonEmpty a -> b) -> [a] -> Maybe b
+ Prelude: void :: Functor f => f a -> f ()
+ Prelude: when :: Applicative f => Bool -> f () -> f ()
+ Prelude: whenJustM :: Monad m => m (Maybe a) -> (a -> m ()) -> m ()
+ Prelude: whenLeft :: Applicative f => a -> Either l r -> (l -> f a) -> f a
+ Prelude: whenLeftM :: Monad m => a -> m (Either l r) -> (l -> m a) -> m a
+ Prelude: whenLeftM_ :: Monad m => m (Either l r) -> (l -> m ()) -> m ()
+ Prelude: whenLeft_ :: Applicative f => Either l r -> (l -> f ()) -> f ()
+ Prelude: whenM :: Monad m => m Bool -> m () -> m ()
+ Prelude: whenNotNull :: Applicative f => [a] -> (NonEmpty a -> f ()) -> f ()
+ Prelude: whenNotNullM :: Monad m => m [a] -> (NonEmpty a -> m ()) -> m ()
+ Prelude: whenNothingM :: Monad m => m (Maybe a) -> m a -> m a
+ Prelude: whenNothingM_ :: Monad m => m (Maybe a) -> m () -> m ()
+ Prelude: whenNothing_ :: Applicative f => Maybe a -> f () -> f ()
+ Prelude: whenRight :: Applicative f => a -> Either l r -> (r -> f a) -> f a
+ Prelude: whenRightM :: Monad m => a -> m (Either l r) -> (r -> m a) -> m a
+ Prelude: whenRightM_ :: Monad m => m (Either l r) -> (r -> m ()) -> m ()
+ Prelude: whenRight_ :: Applicative f => Either l r -> (r -> f ()) -> f ()
+ Prelude: withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
+ Prelude: withFrozenCallStack :: HasCallStack => (HasCallStack => a) -> a
+ Prelude: withReader :: (r' -> r) -> Reader r a -> Reader r' a
+ Prelude: withReaderT :: forall r' r (m :: Type -> Type) a. (r' -> r) -> ReaderT r m a -> ReaderT r' m a
+ Prelude: withState :: (s -> s) -> State s a -> State s a
+ Prelude: words :: IsText t "words" => t -> [t]
+ Prelude: writeFile :: MonadIO m => FilePath -> String -> m ()
+ Prelude: writeFileBS :: MonadIO m => FilePath -> ByteString -> m ()
+ Prelude: writeFileLBS :: MonadIO m => FilePath -> LByteString -> m ()
+ Prelude: writeFileLText :: MonadIO m => FilePath -> LText -> m ()
+ Prelude: writeFileText :: MonadIO m => FilePath -> Text -> m ()
+ Prelude: writeIORef :: MonadIO m => IORef a -> a -> m ()
+ Prelude: writeTVar :: TVar a -> a -> STM ()
+ Prelude: xor :: Bits a => a -> a -> a
+ Prelude: zip :: [a] -> [b] -> [(a, b)]
+ Prelude: zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]
+ Prelude: zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
+ Prelude: zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c]
+ Prelude: zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m ()
+ Prelude: }
- Nix: evaluateExpression :: (MonadNix e t f m, Has e Options) => Maybe FilePath -> (Maybe FilePath -> NExprLoc -> m (NValue t f m)) -> (NValue t f m -> m a) -> NExprLoc -> m a
+ Nix: evaluateExpression :: (MonadNix e t f m, Has e Options) => Maybe Path -> (Maybe Path -> NExprLoc -> m (NValue t f m)) -> (NValue t f m -> m a) -> NExprLoc -> m a
- Nix: nixEvalExpr :: (MonadNix e t f m, Has e Options) => Maybe FilePath -> NExpr -> m (NValue t f m)
+ Nix: nixEvalExpr :: (MonadNix e t f m, Has e Options) => Maybe Path -> NExpr -> m (NValue t f m)
- Nix: nixEvalExprLoc :: forall e t f m. (MonadNix e t f m, Has e Options) => Maybe FilePath -> NExprLoc -> m (NValue t f m)
+ Nix: nixEvalExprLoc :: forall e t f m. (MonadNix e t f m, Has e Options) => Maybe Path -> NExprLoc -> m (NValue t f m)
- Nix: nixTracingEvalExprLoc :: (MonadNix e t f m, Has e Options, MonadIO m, Alternative m) => Maybe FilePath -> NExprLoc -> m (NValue t f m)
+ Nix: nixTracingEvalExprLoc :: (MonadNix e t f m, Has e Options, MonadIO m, Alternative m) => Maybe Path -> NExprLoc -> m (NValue t f m)
- Nix: withNixContext :: forall e t f m r. (MonadNix e t f m, Has e Options) => Maybe FilePath -> m r -> m r
+ Nix: withNixContext :: forall e t f m r. (MonadNix e t f m, Has e Options) => Maybe Path -> m r -> m r
- Nix.Builtins: builtins :: (MonadNix e t f m, Scoped (NValue t f m) m) => m (Scopes m (NValue t f m))
+ Nix.Builtins: builtins :: forall e t f m. (MonadNix e t f m, Scoped (NValue t f m) m) => m (Scopes m (NValue t f m))
- Nix.Builtins: withNixContext :: forall e t f m r. (MonadNix e t f m, Has e Options) => Maybe FilePath -> m r -> m r
+ Nix.Builtins: withNixContext :: forall e t f m r. (MonadNix e t f m, Has e Options) => Maybe Path -> m r -> m r
- Nix.Cache: readCache :: FilePath -> IO NExprLoc
+ Nix.Cache: readCache :: Path -> IO NExprLoc
- Nix.Cache: writeCache :: FilePath -> NExprLoc -> IO ()
+ Nix.Cache: writeCache :: Path -> NExprLoc -> IO ()
- Nix.Cited: cited :: forall f t a (m :: Type -> Type) v. Functor f => (t -> f a) -> NCited m v t -> f (NCited m v a)
+ Nix.Cited: cited :: forall {f} {t} {a} {m :: Type -> Type} {v}. Functor f => (t -> f a) -> NCited m v t -> f (NCited m v a)
- Nix.Cited: lexicalScope :: forall f (m1 :: Type -> Type) v (m2 :: Type -> Type). Functor f => (Scopes m1 v -> f (Scopes m2 v)) -> Provenance m1 v -> f (Provenance m2 v)
+ Nix.Cited: lexicalScope :: forall {f} {m1 :: Type -> Type} {v} {m2 :: Type -> Type}. Functor f => (Scopes m1 v -> f (Scopes m2 v)) -> Provenance m1 v -> f (Provenance m2 v)
- Nix.Cited: originExpr :: forall f v (m :: Type -> Type). Functor f => (NExprLocF (Maybe v) -> f (NExprLocF (Maybe v))) -> Provenance m v -> f (Provenance m v)
+ Nix.Cited: originExpr :: forall {f} {v} {m :: Type -> Type}. Functor f => (NExprLocF (Maybe v) -> f (NExprLocF (Maybe v))) -> Provenance m v -> f (Provenance m v)
- Nix.Cited: provenance :: forall f (m1 :: Type -> Type) v1 (m2 :: Type -> Type) v2 a. Functor f => ([Provenance m1 v1] -> f [Provenance m2 v2]) -> NCited m1 v1 a -> f (NCited m2 v2 a)
+ Nix.Cited: provenance :: forall {f} {m1 :: Type -> Type} {v1} {m2 :: Type -> Type} {v2} {a}. Functor f => ([Provenance m1 v1] -> f [Provenance m2 v2]) -> NCited m1 v1 a -> f (NCited m2 v2 a)
- Nix.Effects: StorePath :: FilePath -> StorePath
+ Nix.Effects: StorePath :: Path -> StorePath
- Nix.Effects: addPath :: (Framed e m, MonadStore m) => FilePath -> m StorePath
+ Nix.Effects: addPath :: (Framed e m, MonadStore m) => Path -> m StorePath
- Nix.Effects: addToStore :: (MonadStore m, MonadTrans t, MonadStore m', m ~ t m') => StorePathName -> FilePath -> RecursiveFlag -> RepairFlag -> m (Either ErrorCall StorePath)
+ Nix.Effects: addToStore :: (MonadStore m, MonadTrans t, MonadStore m', m ~ t m') => StorePathName -> Path -> RecursiveFlag -> RepairFlag -> m (Either ErrorCall StorePath)
- Nix.Effects: class Monad m => MonadPutStr m
+ Nix.Effects: class (Monad m, MonadIO m) => MonadPutStr m
- Nix.Effects: findEnvPath :: MonadEffects t f m => String -> m FilePath
+ Nix.Effects: findEnvPath :: MonadEffects t f m => String -> m Path
- Nix.Effects: findPath :: MonadEffects t f m => [NValue t f m] -> FilePath -> m FilePath
+ Nix.Effects: findPath :: MonadEffects t f m => [NValue t f m] -> Path -> m Path
- Nix.Effects: getDataDir :: (MonadPaths m, MonadTrans t, MonadPaths m', m ~ t m') => m FilePath
+ Nix.Effects: getDataDir :: (MonadPaths m, MonadTrans t, MonadPaths m', m ~ t m') => m Path
- Nix.Effects: importPath :: MonadEffects t f m => FilePath -> m (NValue t f m)
+ Nix.Effects: importPath :: MonadEffects t f m => Path -> m (NValue t f m)
- Nix.Effects: pathToDefaultNix :: MonadEffects t f m => FilePath -> m FilePath
+ Nix.Effects: pathToDefaultNix :: MonadEffects t f m => Path -> m Path
- Nix.Effects: toFile_ :: (Framed e m, MonadStore m) => FilePath -> String -> m StorePath
+ Nix.Effects: toFile_ :: (Framed e m, MonadStore m) => Path -> Text -> m StorePath
- Nix.Effects.Basic: (<///>) :: FilePath -> FilePath -> FilePath
+ Nix.Effects.Basic: (<///>) :: Path -> Path -> Path
- Nix.Effects.Basic: defaultFindEnvPath :: MonadNix e t f m => String -> m FilePath
+ Nix.Effects.Basic: defaultFindEnvPath :: MonadNix e t f m => String -> m Path
- Nix.Effects.Basic: defaultFindPath :: MonadNix e t f m => [NValue t f m] -> FilePath -> m FilePath
+ Nix.Effects.Basic: defaultFindPath :: MonadNix e t f m => [NValue t f m] -> Path -> m Path
- Nix.Effects.Basic: defaultImportPath :: (MonadNix e t f m, MonadState (HashMap FilePath NExprLoc, b) m) => FilePath -> m (NValue t f m)
+ Nix.Effects.Basic: defaultImportPath :: (MonadNix e t f m, MonadState (HashMap Path NExprLoc, b) m) => Path -> m (NValue t f m)
- Nix.Effects.Basic: defaultPathToDefaultNix :: MonadNix e t f m => FilePath -> m FilePath
+ Nix.Effects.Basic: defaultPathToDefaultNix :: MonadNix e t f m => Path -> m Path
- Nix.Effects.Basic: expandHomePath :: MonadFile m => FilePath -> m FilePath
+ Nix.Effects.Basic: expandHomePath :: MonadFile m => Path -> m Path
- Nix.Effects.Basic: findEnvPathM :: forall e t f m. MonadNix e t f m => FilePath -> m FilePath
+ Nix.Effects.Basic: findEnvPathM :: forall e t f m. MonadNix e t f m => Path -> m Path
- Nix.Effects.Basic: findPathBy :: forall e t f m. MonadNix e t f m => (FilePath -> m (Maybe FilePath)) -> [NValue t f m] -> FilePath -> m FilePath
+ Nix.Effects.Basic: findPathBy :: forall e t f m. MonadNix e t f m => (Path -> m (Maybe Path)) -> [NValue t f m] -> Path -> m Path
- Nix.Effects.Basic: findPathM :: forall e t f m. MonadNix e t f m => [NValue t f m] -> FilePath -> m FilePath
+ Nix.Effects.Basic: findPathM :: forall e t f m. MonadNix e t f m => [NValue t f m] -> Path -> m Path
- Nix.Effects.Basic: pathToDefaultNixFile :: MonadFile m => FilePath -> m FilePath
+ Nix.Effects.Basic: pathToDefaultNixFile :: MonadFile m => Path -> m Path
- Nix.Effects.Basic: removeDotDotIndirections :: FilePath -> FilePath
+ Nix.Effects.Basic: removeDotDotIndirections :: Path -> Path
- Nix.Effects.Derivation: defaultDerivationStrict :: forall e t f m b. (MonadNix e t f m, MonadState (b, AttrSet Text) m) => NValue t f m -> m (NValue t f m)
+ Nix.Effects.Derivation: defaultDerivationStrict :: forall e t f m b. (MonadNix e t f m, MonadState (b, KeyMap Text) m) => NValue t f m -> m (NValue t f m)
- Nix.Eval: attrMissing :: MonadEval v m => NonEmpty Text -> Maybe v -> m v
+ Nix.Eval: attrMissing :: MonadEval v m => NonEmpty VarName -> Maybe v -> m v
- Nix.Eval: attrSetAlter :: forall v m. MonadNixEval v m => [Text] -> SourcePos -> AttrSet (m v) -> AttrSet SourcePos -> m v -> m (AttrSet (m v), AttrSet SourcePos)
+ Nix.Eval: attrSetAlter :: forall v m. MonadNixEval v m => [VarName] -> SourcePos -> AttrSet (m v) -> PositionSet -> m v -> m (AttrSet (m v), PositionSet)
- Nix.Eval: evalBinds :: forall v m. MonadNixEval v m => Bool -> [Binding (m v)] -> m (AttrSet v, AttrSet SourcePos)
+ Nix.Eval: evalBinds :: forall v m. MonadNixEval v m => Bool -> [Binding (m v)] -> m (AttrSet v, PositionSet)
- Nix.Eval: evalEnvPath :: MonadEval v m => FilePath -> m v
+ Nix.Eval: evalEnvPath :: MonadEval v m => Path -> m v
- Nix.Eval: evalGetterKeyName :: forall v m. (MonadEval v m, FromValue NixString m v) => NKeyName (m v) -> m Text
+ Nix.Eval: evalGetterKeyName :: forall v m. (MonadEval v m, FromValue NixString m v) => NKeyName (m v) -> m VarName
- Nix.Eval: evalLiteralPath :: MonadEval v m => FilePath -> m v
+ Nix.Eval: evalLiteralPath :: MonadEval v m => Path -> m v
- Nix.Eval: evalSelect :: forall v m. MonadNixEval v m => m v -> NAttrPath (m v) -> m (Either (v, NonEmpty Text) (m v))
+ Nix.Eval: evalSelect :: forall v m. MonadNixEval v m => m v -> NAttrPath (m v) -> m (Either (v, NonEmpty VarName) (m v))
- Nix.Eval: evalSetterKeyName :: (MonadEval v m, FromValue NixString m v) => NKeyName (m v) -> m (Maybe Text)
+ Nix.Eval: evalSetterKeyName :: (MonadEval v m, FromValue NixString m v) => NKeyName (m v) -> m (Maybe VarName)
- Nix.Eval: evaledSym :: MonadEval v m => Text -> v -> m v
+ Nix.Eval: evaledSym :: MonadEval v m => VarName -> v -> m v
- Nix.Eval: freeVariable :: MonadEval v m => Text -> m v
+ Nix.Eval: freeVariable :: MonadEval v m => VarName -> m v
- Nix.Eval: synHole :: MonadEval v m => Text -> m v
+ Nix.Eval: synHole :: MonadEval v m => VarName -> m v
- Nix.Eval: type MonadNixEval v m = (MonadEval v m, Scoped v m, MonadValue v m, MonadFix m, ToValue Bool m v, ToValue [v] m v, FromValue NixString m v, ToValue (AttrSet v, AttrSet SourcePos) m v, FromValue (AttrSet v, AttrSet SourcePos) m v)
+ Nix.Eval: type MonadNixEval v m = (MonadEval v m, Scoped v m, MonadValue v m, MonadFix m, ToValue Bool m v, ToValue [v] m v, FromValue NixString m v, ToValue (AttrSet v, PositionSet) m v, FromValue (AttrSet v, PositionSet) m v)
- Nix.Exec: nvBuiltinP :: MonadCited t f m => Provenance m (NValue t f m) -> Text -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
+ Nix.Exec: nvBuiltinP :: MonadCited t f m => Provenance m (NValue t f m) -> VarName -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
- Nix.Exec: nvPathP :: MonadCited t f m => Provenance m (NValue t f m) -> FilePath -> NValue t f m
+ Nix.Exec: nvPathP :: MonadCited t f m => Provenance m (NValue t f m) -> Path -> NValue t f m
- Nix.Exec: nvSetP :: MonadCited t f m => Provenance m (NValue t f m) -> AttrSet SourcePos -> AttrSet (NValue t f m) -> NValue t f m
+ Nix.Exec: nvSetP :: MonadCited t f m => Provenance m (NValue t f m) -> PositionSet -> AttrSet (NValue t f m) -> NValue t f m
- Nix.Expr.Shorthands: infixl 2 @.
+ Nix.Expr.Shorthands: infixl 2 $||
- Nix.Expr.Shorthands: inherit :: [NKeyName e] -> SourcePos -> Binding e
+ Nix.Expr.Shorthands: inherit :: [VarName] -> Binding e
- Nix.Expr.Shorthands: inheritFrom :: e -> [NKeyName e] -> SourcePos -> Binding e
+ Nix.Expr.Shorthands: inheritFrom :: e -> [VarName] -> Binding e
- Nix.Expr.Types: Inherit :: !Maybe r -> ![NKeyName r] -> !SourcePos -> Binding r
+ Nix.Expr.Types: Inherit :: !Maybe r -> ![VarName] -> !SourcePos -> Binding r
- Nix.Expr.Types: NEnvPath :: !FilePath -> NExprF r
+ Nix.Expr.Types: NEnvPath :: !Path -> NExprF r
- Nix.Expr.Types: NLiteralPath :: !FilePath -> NExprF r
+ Nix.Expr.Types: NLiteralPath :: !Path -> NExprF r
- Nix.Expr.Types: NSelect :: !r -> !NAttrPath r -> !Maybe r -> NExprF r
+ Nix.Expr.Types: NSelect :: !Maybe r -> !r -> !NAttrPath r -> NExprF r
- Nix.Expr.Types: NSet :: !NRecordType -> ![Binding r] -> NExprF r
+ Nix.Expr.Types: NSet :: !Recursivity -> ![Binding r] -> NExprF r
- Nix.Expr.Types: ParamSet :: !ParamSet r -> !Bool -> !Maybe VarName -> Params r
+ Nix.Expr.Types: ParamSet :: !Maybe VarName -> !Variadic -> !ParamSet r -> Params r
- Nix.Expr.Types: _Inherit :: Applicative f => ((Maybe r, [NKeyName r], SourcePos) -> f (Maybe r, [NKeyName r], SourcePos)) -> Binding r -> f (Binding r)
+ Nix.Expr.Types: _Inherit :: Applicative f => ((Maybe r, [VarName], SourcePos) -> f (Maybe r, [VarName], SourcePos)) -> Binding r -> f (Binding r)
- Nix.Expr.Types: _NEnvPath :: Applicative f => (FilePath -> f FilePath) -> NExprF r -> f (NExprF r)
+ Nix.Expr.Types: _NEnvPath :: Applicative f => (Path -> f Path) -> NExprF r -> f (NExprF r)
- Nix.Expr.Types: _NLiteralPath :: Applicative f => (FilePath -> f FilePath) -> NExprF r -> f (NExprF r)
+ Nix.Expr.Types: _NLiteralPath :: Applicative f => (Path -> f Path) -> NExprF r -> f (NExprF r)
- Nix.Expr.Types: _NSelect :: Applicative f => ((r, NAttrPath r, Maybe r) -> f (r, NAttrPath r, Maybe r)) -> NExprF r -> f (NExprF r)
+ Nix.Expr.Types: _NSelect :: Applicative f => ((Maybe r, r, NAttrPath r) -> f (Maybe r, r, NAttrPath r)) -> NExprF r -> f (NExprF r)
- Nix.Expr.Types: _NSet :: Applicative f => ((NRecordType, [Binding r]) -> f (NRecordType, [Binding r])) -> NExprF r -> f (NExprF r)
+ Nix.Expr.Types: _NSet :: Applicative f => ((Recursivity, [Binding r]) -> f (Recursivity, [Binding r])) -> NExprF r -> f (NExprF r)
- Nix.Expr.Types: _ParamSet :: Applicative f => ((ParamSet r1, Bool, Maybe VarName) -> f (ParamSet r2, Bool, Maybe VarName)) -> Params r1 -> f (Params r2)
+ Nix.Expr.Types: _ParamSet :: Applicative f => ((Maybe VarName, Variadic, ParamSet r1) -> f (Maybe VarName, Variadic, ParamSet r2)) -> Params r1 -> f (Params r2)
- Nix.Expr.Types: ekey :: NExprAnn ann g => NonEmpty Text -> SourcePos -> Lens' (Fix g) (Maybe (Fix g))
+ Nix.Expr.Types: ekey :: forall ann g. NExprAnn ann g => NonEmpty VarName -> SourcePos -> Lens' (Fix g) (Maybe (Fix g))
- Nix.Expr.Types: hashAt :: VarName -> Lens' (AttrSet v) (Maybe v)
+ Nix.Expr.Types: hashAt :: Functor f => VarName -> (Maybe v -> f (Maybe v)) -> AttrSet v -> f (AttrSet v)
- Nix.Expr.Types.Annotated: [annotated] :: Ann ann a -> a
+ Nix.Expr.Types.Annotated: [annotated] :: AnnUnit ann expr -> expr
- Nix.Expr.Types.Annotated: [annotation] :: Ann ann a -> ann
+ Nix.Expr.Types.Annotated: [annotation] :: AnnUnit ann expr -> ann
- Nix.Expr.Types.Annotated: stripAnnotation :: Functor f => Fix (AnnF ann f) -> Fix f
+ Nix.Expr.Types.Annotated: stripAnnotation :: Functor f => Ann ann f -> Fix f
- Nix.Expr.Types.Annotated: type AnnF ann f = Compose (Ann ann) f
+ Nix.Expr.Types.Annotated: type AnnF ann f = Compose (AnnUnit ann) f
- Nix.Frames: [HRefl] :: forall k1 (a :: k1). a :~~: a
+ Nix.Frames: [HRefl] :: forall {k1} (a :: k1). a :~~: a
- Nix.Frames: [Refl] :: forall k (a :: k). a :~: a
+ Nix.Frames: [Refl] :: forall {k} (a :: k). a :~: a
- Nix.Frames: eqT :: forall k (a :: k) (b :: k). (Typeable a, Typeable b) => Maybe (a :~: b)
+ Nix.Frames: eqT :: forall {k} (a :: k) (b :: k). (Typeable a, Typeable b) => Maybe (a :~: b)
- Nix.Frames: gcast :: forall k (a :: k) (b :: k) c. (Typeable a, Typeable b) => c a -> Maybe (c b)
+ Nix.Frames: gcast :: forall {k} (a :: k) (b :: k) c. (Typeable a, Typeable b) => c a -> Maybe (c b)
- Nix.Frames: gcast1 :: forall k1 k2 c (t :: k2 -> k1) (t' :: k2 -> k1) (a :: k2). (Typeable t, Typeable t') => c (t a) -> Maybe (c (t' a))
+ Nix.Frames: gcast1 :: forall {k1} {k2} c (t :: k2 -> k1) (t' :: k2 -> k1) (a :: k2). (Typeable t, Typeable t') => c (t a) -> Maybe (c (t' a))
- Nix.Frames: gcast2 :: forall k1 k2 k3 c (t :: k2 -> k3 -> k1) (t' :: k2 -> k3 -> k1) (a :: k2) (b :: k3). (Typeable t, Typeable t') => c (t a b) -> Maybe (c (t' a b))
+ Nix.Frames: gcast2 :: forall {k1} {k2} {k3} c (t :: k2 -> k3 -> k1) (t' :: k2 -> k3 -> k1) (a :: k2) (b :: k3). (Typeable t, Typeable t') => c (t a b) -> Maybe (c (t' a b))
- Nix.Frames: typeRep :: forall k proxy (a :: k). Typeable a => proxy a -> TypeRep
+ Nix.Frames: typeRep :: forall {k} proxy (a :: k). Typeable a => proxy a -> TypeRep
- Nix.Lint: TSet :: Maybe (HashMap Text r) -> NTypeF (m :: Type -> Type) r
+ Nix.Lint: TSet :: Maybe (AttrSet r) -> NTypeF (m :: Type -> Type) r
- Nix.Options: Options :: Verbosity -> Bool -> Bool -> Bool -> Bool -> Maybe FilePath -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe FilePath -> Bool -> Bool -> Bool -> Bool -> Maybe Text -> [FilePath] -> Bool -> Maybe FilePath -> Bool -> Bool -> Bool -> Maybe Text -> [(Text, Text)] -> [(Text, Text)] -> Maybe FilePath -> UTCTime -> [FilePath] -> Options
+ Nix.Options: Options :: Verbosity -> Bool -> Bool -> Bool -> Bool -> Maybe Path -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe Path -> Bool -> Bool -> Bool -> Bool -> Maybe Text -> [Path] -> Bool -> Maybe Path -> Bool -> Bool -> Bool -> Maybe Text -> [(Text, Text)] -> [(Text, Text)] -> Maybe Path -> UTCTime -> [Path] -> Options
- Nix.Options: [filePaths] :: Options -> [FilePath]
+ Nix.Options: [filePaths] :: Options -> [Path]
- Nix.Options: [findFile] :: Options -> Maybe FilePath
+ Nix.Options: [findFile] :: Options -> Maybe Path
- Nix.Options: [fromFile] :: Options -> Maybe FilePath
+ Nix.Options: [fromFile] :: Options -> Maybe Path
- Nix.Options: [include] :: Options -> [FilePath]
+ Nix.Options: [include] :: Options -> [Path]
- Nix.Options: [readFrom] :: Options -> Maybe FilePath
+ Nix.Options: [readFrom] :: Options -> Maybe Path
- Nix.Options: [reduce] :: Options -> Maybe FilePath
+ Nix.Options: [reduce] :: Options -> Maybe Path
- Nix.Parser: nixSelector :: Parser (Ann SrcSpan (NAttrPath NExprLoc))
+ Nix.Parser: nixSelector :: Parser (AnnUnit SrcSpan (NAttrPath NExprLoc))
- Nix.Parser: parseFromFileEx :: MonadFile m => Parser a -> FilePath -> m (Result a)
+ Nix.Parser: parseFromFileEx :: MonadFile m => Parser a -> Path -> m (Result a)
- Nix.Parser: parseNixFile :: MonadFile m => FilePath -> m (Result NExpr)
+ Nix.Parser: parseNixFile :: MonadFile m => Path -> m (Result NExpr)
- Nix.Parser: parseNixFileLoc :: MonadFile m => FilePath -> m (Result NExprLoc)
+ Nix.Parser: parseNixFileLoc :: MonadFile m => Path -> m (Result NExprLoc)
- Nix.Parser: reservedNames :: HashSet Text
+ Nix.Parser: reservedNames :: HashSet VarName
- Nix.Pretty: prettyParamSet :: ParamSet (NixDoc ann) -> Bool -> Doc ann
+ Nix.Pretty: prettyParamSet :: Variadic -> ParamSet (NixDoc ann) -> Doc ann
- Nix.Pretty: printNix :: forall t f m. MonadDataContext f m => NValue t f m -> String
+ Nix.Pretty: printNix :: forall t f m. MonadDataContext f m => NValue t f m -> Text
- Nix.Reduce: reduceExpr :: (MonadIO m, MonadFail m) => Maybe FilePath -> NExprLoc -> m NExprLoc
+ Nix.Reduce: reduceExpr :: (MonadIO m, MonadFail m) => Maybe Path -> NExprLoc -> m NExprLoc
- Nix.Reduce: reducingEvalExpr :: (Framed e m, Has e Options, Exception r, MonadCatch m, MonadIO m) => (NExprLocF (m a) -> m a) -> Maybe FilePath -> NExprLoc -> m (NExprLoc, Either r a)
+ Nix.Reduce: reducingEvalExpr :: (Framed e m, Has e Options, Exception r, MonadCatch m, MonadIO m) => (NExprLocF (m a) -> m a) -> Maybe Path -> NExprLoc -> m (NExprLoc, Either r a)
- Nix.Render: canonicalizePath :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m FilePath
+ Nix.Render: canonicalizePath :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => Path -> m Path
- Nix.Render: class MonadFail m => MonadFile m
+ Nix.Render: class (MonadFail m, MonadIO m) => MonadFile m
- Nix.Render: doesDirectoryExist :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool
+ Nix.Render: doesDirectoryExist :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => Path -> m Bool
- Nix.Render: doesFileExist :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool
+ Nix.Render: doesFileExist :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => Path -> m Bool
- Nix.Render: doesPathExist :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool
+ Nix.Render: doesPathExist :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => Path -> m Bool
- Nix.Render: errorContext :: FilePath -> Pos -> Pos -> Pos -> Pos -> Doc a
+ Nix.Render: errorContext :: Path -> Pos -> Pos -> Pos -> Pos -> Doc a
- Nix.Render: getCurrentDirectory :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => m FilePath
+ Nix.Render: getCurrentDirectory :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => m Path
- Nix.Render: getHomeDirectory :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => m FilePath
+ Nix.Render: getHomeDirectory :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => m Path
- Nix.Render: getSymbolicLinkStatus :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m FileStatus
+ Nix.Render: getSymbolicLinkStatus :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => Path -> m FileStatus
- Nix.Render: listDirectory :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m [FilePath]
+ Nix.Render: listDirectory :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => Path -> m [Path]
- Nix.Render: readFile :: (MonadFile m, MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m ByteString
+ Nix.Render: readFile :: (MonadFile m, MonadTrans t, MonadIO m', MonadFile m', m ~ t m') => Path -> m Text
- Nix.Render: sourceContext :: MonadFile m => FilePath -> Pos -> Pos -> Pos -> Pos -> Doc a -> m (Doc a)
+ Nix.Render: sourceContext :: MonadFile m => Path -> Pos -> Pos -> Pos -> Pos -> Doc a -> m (Doc a)
- Nix.Render.Frame: renderEvalFrame :: (MonadReader e m, Has e Options, MonadFile m) => NixLevel -> EvalFrame m v -> m [Doc ann]
+ Nix.Render.Frame: renderEvalFrame :: forall e m v ann. (MonadReader e m, Has e Options, MonadFile m) => NixLevel -> EvalFrame m v -> m [Doc ann]
- Nix.Scope: emptyScopes :: forall m a. Scopes m a
+ Nix.Scope: emptyScopes :: Scopes m a
- Nix.Scope: lookupVar :: Scoped a m => Text -> m (Maybe a)
+ Nix.Scope: lookupVar :: Scoped a m => VarName -> m (Maybe a)
- Nix.Scope: lookupVarReader :: forall m a e. (MonadReader e m, Has e (Scopes m a)) => Text -> m (Maybe a)
+ Nix.Scope: lookupVarReader :: forall m a e. (MonadReader e m, Has e (Scopes m a)) => VarName -> m (Maybe a)
- Nix.Scope: pushScope :: Scoped a m => AttrSet a -> m r -> m r
+ Nix.Scope: pushScope :: Scoped a m => Scope a -> m r -> m r
- Nix.Scope: pushWeakScope :: (Functor m, Scoped a m) => m (AttrSet a) -> m r -> m r
+ Nix.Scope: pushWeakScope :: (Functor m, Scoped a m) => m (Scope a) -> m r -> m r
- Nix.Scope: scopeLookup :: Text -> [Scope a] -> Maybe a
+ Nix.Scope: scopeLookup :: VarName -> [Scope a] -> Maybe a
- Nix.Standard: StandardTF :: ReaderT (Context r (StdValue r)) (StateT (HashMap FilePath NExprLoc, HashMap Text Text) m) a -> StandardTF r m a
+ Nix.Standard: StandardTF :: ReaderT (Context r (StdValue r)) (StateT (HashMap Path NExprLoc, HashMap Text Text) m) a -> StandardTF r m a
- Nix.Standard: StdThunk :: StdCited m (NThunkF m (StdValue m)) -> StdThunk (m :: Type -> Type)
+ Nix.Standard: StdThunk :: StdCited m (NThunkF m (StdValue m)) -> StdThunk m
- Nix.Standard: mkStandardT :: ReaderT (Context (StandardT m) (StdValue (StandardT m))) (StateT (HashMap FilePath NExprLoc, HashMap Text Text) m) a -> StandardT m a
+ Nix.Standard: mkStandardT :: ReaderT (Context (StandardT m) (StdValue (StandardT m))) (StateT (HashMap Path NExprLoc, HashMap Text Text) m) a -> StandardT m a
- Nix.Standard: newtype StdThunk (m :: Type -> Type)
+ Nix.Standard: newtype StdThunk m
- Nix.Standard: runStandardT :: StandardT m a -> ReaderT (Context (StandardT m) (StdValue (StandardT m))) (StateT (HashMap FilePath NExprLoc, HashMap Text Text) m) a
+ Nix.Standard: runStandardT :: StandardT m a -> ReaderT (Context (StandardT m) (StdValue (StandardT m))) (StateT (HashMap Path NExprLoc, HashMap Text Text) m) a
- Nix.String: StringContext :: !Text -> !ContextFlavor -> StringContext
+ Nix.String: StringContext :: !VarName -> !ContextFlavor -> StringContext
- Nix.String: [scPath] :: StringContext -> !Text
+ Nix.String: [scPath] :: StringContext -> !VarName
- Nix.Type.Assumption: Assumption :: [(Name, Type)] -> Assumption
+ Nix.Type.Assumption: Assumption :: [(VarName, Type)] -> Assumption
- Nix.Type.Assumption: extend :: Assumption -> (Name, Type) -> Assumption
+ Nix.Type.Assumption: extend :: Assumption -> (VarName, Type) -> Assumption
- Nix.Type.Assumption: keys :: Assumption -> [Name]
+ Nix.Type.Assumption: keys :: Assumption -> [VarName]
- Nix.Type.Assumption: lookup :: Name -> Assumption -> [Type]
+ Nix.Type.Assumption: lookup :: VarName -> Assumption -> [Type]
- Nix.Type.Assumption: remove :: Assumption -> Name -> Assumption
+ Nix.Type.Assumption: remove :: Assumption -> VarName -> Assumption
- Nix.Type.Assumption: singleton :: Name -> Type -> Assumption
+ Nix.Type.Assumption: singleton :: VarName -> Type -> Assumption
- Nix.Type.Env: TypeEnv :: Map Name [Scheme] -> Env
+ Nix.Type.Env: TypeEnv :: Map VarName [Scheme] -> Env
- Nix.Type.Env: extend :: Env -> (Name, [Scheme]) -> Env
+ Nix.Type.Env: extend :: Env -> (VarName, [Scheme]) -> Env
- Nix.Type.Env: extends :: Env -> [(Name, [Scheme])] -> Env
+ Nix.Type.Env: extends :: Env -> [(VarName, [Scheme])] -> Env
- Nix.Type.Env: fromList :: [(Name, [Scheme])] -> Env
+ Nix.Type.Env: fromList :: [(VarName, [Scheme])] -> Env
- Nix.Type.Env: keys :: Env -> [Name]
+ Nix.Type.Env: keys :: Env -> [VarName]
- Nix.Type.Env: lookup :: Name -> Env -> Maybe [Scheme]
+ Nix.Type.Env: lookup :: VarName -> Env -> Maybe [Scheme]
- Nix.Type.Env: remove :: Env -> Name -> Env
+ Nix.Type.Env: remove :: Env -> VarName -> Env
- Nix.Type.Env: singleton :: Name -> Scheme -> Env
+ Nix.Type.Env: singleton :: VarName -> Scheme -> Env
- Nix.Type.Env: toList :: Env -> [(Name, [Scheme])]
+ Nix.Type.Env: toList :: Env -> [(VarName, [Scheme])]
- Nix.Type.Infer: UnboundVariables :: [Text] -> TypeError
+ Nix.Type.Infer: UnboundVariables :: [VarName] -> TypeError
- Nix.Type.Infer: inferTop :: Env -> [(Text, NExpr)] -> Either InferError Env
+ Nix.Type.Infer: inferTop :: Env -> [(VarName, NExpr)] -> Either InferError Env
- Nix.Type.Type: TSet :: Bool -> AttrSet Type -> Type
+ Nix.Type.Type: TSet :: Variadic -> AttrSet Type -> Type
- Nix.Type.Type: typeFun :: [Type] -> Type
+ Nix.Type.Type: typeFun :: NonEmpty Type -> Type
- Nix.Value: NVBuiltinF :: Text -> (p -> m r) -> NValueF p m r
+ Nix.Value: NVBuiltinF :: VarName -> (p -> m r) -> NValueF p m r
- Nix.Value: NVPathF :: FilePath -> NValueF p m r
+ Nix.Value: NVPathF :: Path -> NValueF p m r
- Nix.Value: NVSetF :: AttrSet r -> AttrSet SourcePos -> NValueF p m r
+ Nix.Value: NVSetF :: PositionSet -> AttrSet r -> NValueF p m r
- Nix.Value: _NVBuiltinF :: Applicative f => ((Text, p -> m r) -> f (Text, p -> m r)) -> NValueF p m r -> f (NValueF p m r)
+ Nix.Value: _NVBuiltinF :: Applicative f => ((VarName, p -> m r) -> f (VarName, p -> m r)) -> NValueF p m r -> f (NValueF p m r)
- Nix.Value: _NVConstantF :: forall f p (m :: Type -> Type) r. Applicative f => (NAtom -> f NAtom) -> NValueF p m r -> f (NValueF p m r)
+ Nix.Value: _NVConstantF :: forall {f} {p} {m :: Type -> Type} {r}. Applicative f => (NAtom -> f NAtom) -> NValueF p m r -> f (NValueF p m r)
- Nix.Value: _NVListF :: forall f r p (m :: Type -> Type). Applicative f => ([r] -> f [r]) -> NValueF p m r -> f (NValueF p m r)
+ Nix.Value: _NVListF :: forall {f} {r} {p} {m :: Type -> Type}. Applicative f => ([r] -> f [r]) -> NValueF p m r -> f (NValueF p m r)
- Nix.Value: _NVPathF :: forall f p (m :: Type -> Type) r. Applicative f => (FilePath -> f FilePath) -> NValueF p m r -> f (NValueF p m r)
+ Nix.Value: _NVPathF :: forall {f} {p} {m :: Type -> Type} {r}. Applicative f => (Path -> f Path) -> NValueF p m r -> f (NValueF p m r)
- Nix.Value: _NVSetF :: forall f r p (m :: Type -> Type). Applicative f => ((AttrSet r, AttrSet SourcePos) -> f (AttrSet r, AttrSet SourcePos)) -> NValueF p m r -> f (NValueF p m r)
+ Nix.Value: _NVSetF :: forall {f} {r} {p} {m :: Type -> Type}. Applicative f => ((PositionSet, AttrSet r) -> f (PositionSet, AttrSet r)) -> NValueF p m r -> f (NValueF p m r)
- Nix.Value: _NVStrF :: forall f p (m :: Type -> Type) r. Applicative f => (NixString -> f NixString) -> NValueF p m r -> f (NValueF p m r)
+ Nix.Value: _NVStrF :: forall {f} {p} {m :: Type -> Type} {r}. Applicative f => (NixString -> f NixString) -> NValueF p m r -> f (NValueF p m r)
- Nix.Value: builtin :: forall m f t. (MonadThunk t m (NValue t f m), MonadDataContext f m) => Text -> (NValue t f m -> m (NValue t f m)) -> m (NValue t f m)
+ Nix.Value: builtin :: forall m f t. (MonadThunk t m (NValue t f m), MonadDataContext f m) => VarName -> (NValue t f m -> m (NValue t f m)) -> m (NValue t f m)
- Nix.Value: builtin2 :: (MonadThunk t m (NValue t f m), MonadDataContext f m) => Text -> (NValue t f m -> NValue t f m -> m (NValue t f m)) -> m (NValue t f m)
+ Nix.Value: builtin2 :: (MonadThunk t m (NValue t f m), MonadDataContext f m) => VarName -> (NValue t f m -> NValue t f m -> m (NValue t f m)) -> m (NValue t f m)
- Nix.Value: builtin3 :: (MonadThunk t m (NValue t f m), MonadDataContext f m) => Text -> (NValue t f m -> NValue t f m -> NValue t f m -> m (NValue t f m)) -> m (NValue t f m)
+ Nix.Value: builtin3 :: (MonadThunk t m (NValue t f m), MonadDataContext f m) => VarName -> (NValue t f m -> NValue t f m -> NValue t f m -> m (NValue t f m)) -> m (NValue t f m)
- Nix.Value: nValue :: forall f1 f2 t1 (m1 :: Type -> Type) a1 f3 t2 (m2 :: Type -> Type) a2. Functor f1 => (f2 (NValueF (NValue t1 f2 m1) m1 a1) -> f1 (f3 (NValueF (NValue t2 f3 m2) m2 a2))) -> NValue' t1 f2 m1 a1 -> f1 (NValue' t2 f3 m2 a2)
+ Nix.Value: nValue :: forall {f1} {f2} {t1} {m1 :: Type -> Type} {a1} {f3} {t2} {m2 :: Type -> Type} {a2}. Functor f1 => (f2 (NValueF (NValue t1 f2 m1) m1 a1) -> f1 (f3 (NValueF (NValue t2 f3 m2) m2 a2))) -> NValue' t1 f2 m1 a1 -> f1 (NValue' t2 f3 m2 a2)
- Nix.Value: nvBuiltin :: (Applicative f, Functor m) => Text -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
+ Nix.Value: nvBuiltin :: (Applicative f, Functor m) => VarName -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
- Nix.Value: nvBuiltin' :: (Applicative f, Functor m) => Text -> (NValue t f m -> m r) -> NValue' t f m r
+ Nix.Value: nvBuiltin' :: (Applicative f, Functor m) => VarName -> (NValue t f m -> m r) -> NValue' t f m r
- Nix.Value: nvPath :: Applicative f => FilePath -> NValue t f m
+ Nix.Value: nvPath :: Applicative f => Path -> NValue t f m
- Nix.Value: nvPath' :: Applicative f => FilePath -> NValue' t f m r
+ Nix.Value: nvPath' :: Applicative f => Path -> NValue' t f m r
- Nix.Value: nvSet :: Applicative f => AttrSet SourcePos -> AttrSet (NValue t f m) -> NValue t f m
+ Nix.Value: nvSet :: Applicative f => PositionSet -> AttrSet (NValue t f m) -> NValue t f m
- Nix.Value: nvSet' :: Applicative f => AttrSet SourcePos -> AttrSet r -> NValue' t f m r
+ Nix.Value: nvSet' :: Applicative f => PositionSet -> AttrSet r -> NValue' t f m r
- Nix.Value: pattern NVConstant :: forall (w :: Type -> Type) t (m :: Type -> Type) a. Comonad w => NAtom -> Free (NValue' t w m) a
+ Nix.Value: pattern NVConstant :: forall {w :: Type -> Type} {t} {m :: Type -> Type} {a}. Comonad w => NAtom -> Free (NValue' t w m) a
- Nix.Value: pattern NVThunk :: forall f a. a -> Free f a
+ Nix.Value: pattern NVThunk :: forall {f} {a}. a -> Free f a
- Nix.Value: pattern NVStr :: forall (w :: Type -> Type) t (m :: Type -> Type) a. Comonad w => NixString -> Free (NValue' t w m) a
+ Nix.Value: pattern NVStr :: forall {w :: Type -> Type} {t} {m :: Type -> Type} {a}. Comonad w => NixString -> Free (NValue' t w m) a
- Nix.Value: pattern NVClosure :: forall (w :: Type -> Type) t m a. Comonad w => Params () -> (NValue t w m -> m (Free (NValue' t w m) a)) -> Free (NValue' t w m) a
+ Nix.Value: pattern NVClosure :: forall {w :: Type -> Type} {t} {m} {a}. Comonad w => Params () -> (NValue t w m -> m (Free (NValue' t w m) a)) -> Free (NValue' t w m) a
- Nix.Value: pattern NVList :: forall (w :: Type -> Type) t (m :: Type -> Type) a. Comonad w => [Free (NValue' t w m) a] -> Free (NValue' t w m) a
+ Nix.Value: pattern NVList :: forall {w :: Type -> Type} {t} {m :: Type -> Type} {a}. Comonad w => [Free (NValue' t w m) a] -> Free (NValue' t w m) a
- Nix.Value: pattern NVList' :: forall w t m a. Comonad w => [a] -> NValue' t w m a
+ Nix.Value: pattern NVList' :: forall {w} {t} {m} {a}. Comonad w => [a] -> NValue' t w m a

Files

ChangeLog.md view
@@ -1,7 +1,50 @@  # ChangeLog -## [(diff)](https://github.com/haskell-nix/hnix/compare/0.13.1...0.14.0#files_bucket) 0.14.0+## [(diff)](https://github.com/haskell-nix/hnix/compare/0.14.0...0.15.0#files_bucket) 0.15.0++For support refere to: https://github.com/haskell-nix/hnix/issues/984++Partial log (for now):++* Breaking:++  * `Nix.Expr.Shorthands`:+    * `inherit{,From}`:+      * dropped second(/third) argument as irrelevant ([report](https://github.com/haskell-nix/hnix/issues/326))+      * bindings to inherit changed type from complex `[NKeyName]` (which is for static & dynamic keys) to `[VarName]` (`VarName` is newtype of `Text`).+      * So examples of use now are: `inherit ["a", "b"]`, `inheritFrom (var "a") ["b", "c"]`+    * `mkAssert`: fixed ([report](https://github.com/haskell-nix/hnix/issues/969)).+    * fx presedence between the operators:+        +        ```haskell+        (@@), (@.), (@./), ($==), ($!=), ($<), ($<=), ($>), ($>=), ($&&), ($||), ($->), ($//), ($+), ($-), ($*), ($/), ($++), (==>)+        ```+        +        Now these shorthands can be used without sectioning & so represent the Nix expressions one to one.+        +        ```haskell+        nix = "           a/b   //            c/def   //           <g>  <             def/d"+        hask = mkRelPath "a/b" $// mkRelPath "c/def" $// mkEnvPath "g" $<  mkRelPath "def/d"+        ```++* Additional+  * `Nix.Expr.Shorthands`:+    * added:+      * `emptySet`+      * `emptyList`+      * `mkOp{,2}`+      * `mk{,Named,Variadic,General}ParamSet`+      * `mkNeg` - number negation.+      * `@.<|>` for Nix language `s.x or y` expession.+    * entered deprecation:+      * `mkOper{,2}` bacame `mkOp{,2}`.+      * `mkBinop` became `mkOp2`.+      * `mkParaset` supeceeded by `mk{,Named{,Variadic},Variadic,General}ParamSet`.+    * fixed:+      * `mkAssert` was creating `with`, now properly creates `assert`.++## [(diff)](https://github.com/haskell-nix/hnix/compare/0.13.1...0.14.0#files_bucket) 0.14.0 (2021-07-08)  * GHC 9.0 support. 
benchmarks/Main.hs view
@@ -5,4 +5,4 @@ import qualified ParserBench  main :: IO ()-main = defaultMain [ParserBench.benchmarks]+main = defaultMain $ one ParserBench.benchmarks
benchmarks/ParserBench.hs view
@@ -4,8 +4,8 @@  import           Criterion -benchFile :: FilePath -> Benchmark-benchFile = bench <*> whnfIO . parseNixFile . ("data/" <>)+benchFile :: Path -> Benchmark+benchFile = bench . coerce <*> whnfIO . parseNixFile . ("data/" <>)  benchmarks :: Benchmark benchmarks = bgroup
hnix.cabal view
@@ -1,6 +1,6 @@ cabal-version:  2.2 name:           hnix-version:        0.14.0.8+version:        0.15.0 synopsis:       Haskell implementation of the Nix language description:    Haskell implementation of the Nix language. category:       System, Data, Nix@@ -341,7 +341,9 @@  library   exposed-modules:+    Prelude     Nix+    Nix.Utils     Nix.Atoms     Nix.Builtins     Nix.Cache@@ -383,7 +385,6 @@     Nix.Type.Env     Nix.Type.Infer     Nix.Type.Type-    Nix.Utils     Nix.Utils.Fix1     Nix.Value     Nix.Value.Equal@@ -392,13 +393,13 @@     Nix.XML   other-modules:     Paths_hnix+    Nix.Unused   autogen-modules:     Paths_hnix   hs-source-dirs:     src   mixins:       base hiding (Prelude)-    , relude (Relude as Prelude)     , relude   ghc-options:     -Wall@@ -406,7 +407,7 @@   build-depends:       aeson >= 1.4.2 && < 1.6 || >= 2.0 && < 2.1     , array >= 0.4 && < 0.6-    , base >= 4.12 && < 4.16+    , base >= 4.12 && < 5     , base16-bytestring >= 0.1.1 && < 1.1     , binary >= 0.8.5 && < 0.9     , bytestring >= 0.10.8 && < 0.12@@ -421,7 +422,7 @@     , filepath >= 1.4.2 && < 1.5     , free >= 5.1 && < 5.2     , gitrev >= 1.1.0 && < 1.4-    , hashable >= 1.2.5 && < 1.5+    , hashable >= 1.2.5 && < 1.4     , hashing >= 0.1.0 && < 0.2     , hnix-store-core >= 0.5.0 && < 0.6     , hnix-store-remote >= 0.5.0 && < 0.6@@ -463,7 +464,7 @@     , time >= 1.8.0 && < 1.9 || >= 1.9.3 && < 1.10     , transformers >= 0.5.5 && < 0.6     , transformers-base >= 0.4.5 && < 0.5-    , unix >= 2.7.2 && < 2.8+    , unix-compat >= 0.4.3 && < 0.6     , unordered-containers >= 0.2.9 && < 0.3     , vector >= 0.12.0 && < 0.13     , xml >= 1.3.14 && < 1.4@@ -477,6 +478,7 @@     , DeriveLift     , FlexibleContexts     , FlexibleInstances+    , ScopedTypeVariables     , StandaloneDeriving     , TypeApplications     , TypeSynonymInstances@@ -485,6 +487,7 @@     , TupleSections     , LambdaCase     , BangPatterns+    , ViewPatterns   if flag(optimize)     default-extensions:       ApplicativeDo@@ -531,7 +534,6 @@     , time   mixins:       base hiding (Prelude)-    , relude (Relude as Prelude)     , relude   default-extensions:       OverloadedStrings@@ -543,6 +545,7 @@     , DeriveLift     , FlexibleContexts     , FlexibleInstances+    , ScopedTypeVariables     , StandaloneDeriving     , TypeApplications     , TypeSynonymInstances@@ -551,6 +554,7 @@     , TupleSections     , LambdaCase     , BangPatterns+    , ViewPatterns   if flag(optimize)     default-extensions:       ApplicativeDo@@ -577,7 +581,6 @@     TestCommon   mixins:       base hiding (Prelude)-    , relude (Relude as Prelude)     , relude   hs-source-dirs:     tests@@ -610,7 +613,7 @@     , serialise     , template-haskell     , time-    , unix+    , unix-compat   default-extensions:       OverloadedStrings     , DeriveGeneric@@ -621,6 +624,7 @@     , DeriveLift     , FlexibleContexts     , FlexibleInstances+    , ScopedTypeVariables     , StandaloneDeriving     , TypeApplications     , TypeSynonymInstances@@ -629,6 +633,7 @@     , TupleSections     , LambdaCase     , BangPatterns+    , ViewPatterns   if flag(optimize)     default-extensions:       ApplicativeDo@@ -647,7 +652,6 @@     benchmarks   mixins:       base hiding (Prelude)-    , relude (Relude as Prelude)     , relude   ghc-options:     -Wall@@ -673,6 +677,7 @@     , DeriveLift     , FlexibleContexts     , FlexibleInstances+    , ScopedTypeVariables     , StandaloneDeriving     , TypeApplications     , TypeSynonymInstances@@ -681,6 +686,7 @@     , TupleSections     , LambdaCase     , BangPatterns+    , ViewPatterns   if flag(optimize)     default-extensions:       ApplicativeDo
main/Main.hs view
@@ -1,29 +1,24 @@-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE RecordWildCards #-}+{-# language MultiWayIf #-}+{-# language TypeFamilies #-}+{-# language RecordWildCards #-}  module Main ( main ) where -import           Nix.Utils+import           Relude                        as Prelude ( force ) import           Control.Comonad                ( extract )-import qualified Control.DeepSeq               as Deep-import qualified Control.Exception             as Exc+import qualified Control.Exception             as Exception import           GHC.Err                        ( errorWithoutStackTrace ) import           Control.Monad.Free import           Control.Monad.Ref              ( MonadRef(readRef) ) import           Control.Monad.Catch-import           System.IO                      ( hPutStrLn, getContents )+import           System.IO                      ( hPutStrLn ) import qualified Data.HashMap.Lazy             as M import qualified Data.Map                      as Map-import           Data.Maybe                     ( fromJust )-import qualified Data.String                   as String import           Data.Time import qualified Data.Text.IO                  as Text-import           Nix+import           Text.Show.Pretty               ( ppShow )+import           Nix                     hiding ( force ) import           Nix.Convert-import qualified Nix.Eval                      as Eval import           Nix.Fresh.Basic import           Nix.Json import           Nix.Options.Parser@@ -35,11 +30,9 @@ import           Nix.Value.Monad import           Options.Applicative     hiding ( ParserResult(..) ) import           Prettyprinter           hiding ( list )-import           Prettyprinter.Render.Text+import           Prettyprinter.Render.Text      ( renderIO ) import qualified Repl-import           System.FilePath-import qualified Text.Show.Pretty              as PS-import           Nix.Utils.Fix1                 ( Fix1T )+import           Nix.Eval  main :: IO () main =@@ -50,45 +43,66 @@     main' opts  main' :: Options -> IO ()-main' (opts@Options{..}) = runWithBasicEffectsIO opts execContentsFilesOrRepl+main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl  where+  --  2021-07-15: NOTE: This logic should be weaved stronger through CLI options logic (OptParse-Applicative code)+  -- As this logic is not stated in the CLI documentation, for example. So user has no knowledge of these.+  execContentsFilesOrRepl :: StandardT (StdIdT IO) ()   execContentsFilesOrRepl =-    firstJust-      -- The `--read` option: load expression from a serialized file.-      [ readFrom <&> \path -> do-          let file = addExtension (dropExtension path) "nixc"-          process (Just file) =<< liftIO (readCache path)+    fromMaybe+      loadFromCliFilePathList+      ( loadBinaryCacheFile <|>+        loadLiteralExpression <|>+        loadExpressionFromFile+      )+   where+    -- | The base case: read expressions from the last CLI directive (@[FILE]@) listed on the command line.+    loadFromCliFilePathList =+      case filePaths of+        []     -> runRepl+        ["-"]  -> readExpressionFromStdin+        _paths -> processSeveralFiles (coerce _paths)+     where+      -- | Fall back to running the REPL+      runRepl = withEmptyNixContext Repl.main -      -- The `--expr` option: read expression from the argument string-      , expression <&> processText+      readExpressionFromStdin =+        do+          expr <- liftIO Text.getContents+          processExpr expr -      -- The `--file` argument: read expressions from the files listed in the argument file-      , fromFile <&> \x ->-          -- We can start use Text as in the base case, requires changing FilePath -> Text-          traverse_ processFile . String.lines =<< liftIO-            (case x of-              "-" -> getContents-              fp -> readFile fp-            )-      ]-    `orElse`-      -- The base case: read expressions from the files listed on the command line-      case filePaths of-        -- With no files, fall back to running the REPL-        [] -> withNixContext mempty Repl.main-        ["-"] -> processText =<< liftIO Text.getContents-        _paths -> traverse_ processFile _paths+    processSeveralFiles :: [Path] -> StandardT (StdIdT IO) ()+    processSeveralFiles = traverse_ processFile+     where+      processFile path = handleResult (pure path) =<< parseNixFileLoc path -  firstJust :: [Maybe a] -> Maybe a-  firstJust = asum+    -- |  The `--read` option: load expression from a serialized file.+    loadBinaryCacheFile =+      (\ (binaryCacheFile :: Path) ->+        do+          let file = replaceExtension binaryCacheFile "nixc"+          processCLIOptions (Just file) =<< liftIO (readCache binaryCacheFile)+      ) <$> readFrom -  orElse :: Maybe a -> a -> a-  orElse = flip fromMaybe+    -- | The `--expr` option: read expression from the argument string+    loadLiteralExpression = processExpr <$> expression -  processText text = handleResult Nothing     $   parseNixTextLoc text+    -- | The `--file` argument: read expressions from the files listed in the argument file+    loadExpressionFromFile =+      -- We can start use Text as in the base case, requires changing Path -> Text+      -- But that is a gradual process:+      -- https://github.com/haskell-nix/hnix/issues/912+      (processSeveralFiles . (coerce . toString <$>) . lines <=< liftIO) .+        (\case+          "-" -> Text.getContents+          _fp -> readFile _fp+        ) <$> fromFile -  processFile path = handleResult (Just path) =<< parseNixFileLoc path+  processExpr text = handleResult Nothing     $   parseNixTextLoc text +  withEmptyNixContext = withNixContext mempty++  --  2021-07-15: NOTE: @handleResult@ & @process@ - have atrocious size & compexity, they need to be decomposed & refactored.   handleResult mpath =     either       (\ err ->@@ -103,18 +117,18 @@         do           when check $             do-              expr' <- liftIO (reduceExpr mpath expr)+              expr' <- liftIO $ reduceExpr mpath expr               either-                (\ err -> errorWithoutStackTrace $ "Type error: " <> PS.ppShow err)-                (\ ty  -> liftIO $ putStrLn $ "Type of expression: " <> PS.ppShow-                  (fromJust $ Map.lookup "it" (coerce ty :: Map Text [Scheme]))+                (\ err -> errorWithoutStackTrace $ "Type error: " <> ppShow err)+                (\ ty  -> liftIO $ putStrLn $ "Type of expression: " <>+                  ppShow (maybeToMonoid $ Map.lookup @VarName @[Scheme] "it" $ coerce ty)                 )-                (HM.inferTop mempty [("it", stripAnnotation expr')])+                (HM.inferTop mempty (one ("it", stripAnnotation expr')))                  -- liftIO $ putStrLn $ runST $                 --     runLintM opts . renderSymbolic =<< lint opts expr -          catch (process mpath expr) $+          catch (processCLIOptions mpath expr) $             \case               NixException frames ->                 errorWithoutStackTrace . show =<<@@ -124,30 +138,32 @@                     frames            when repl $-            withNixContext mempty $+            withEmptyNixContext $               bool                 Repl.main                 (do-                  val <- Nix.nixEvalExprLoc mpath expr+                  val <- nixEvalExprLoc (coerce mpath) expr                   Repl.main' $ pure val                 )                 evaluate       ) -  process mpath expr+  --  2021-07-15: NOTE: Logic of CLI Option processing is scattered over several functions, needs to be consolicated.+  processCLIOptions :: Maybe Path -> NExprLoc -> StandardT (StdIdT IO) ()+  processCLIOptions mpath expr     | evaluate =       if-        | tracing                       -> evaluateExpression mpath Nix.nixTracingEvalExprLoc printer expr-        | Just path <- reduce           -> evaluateExpression mpath (reduction path) printer expr-        | not (null arg && null argstr) -> evaluateExpression mpath Nix.nixEvalExprLoc printer expr-        | otherwise                     -> processResult printer =<< Nix.nixEvalExprLoc mpath expr-    | xml                        =  fail "Rendering expression trees to XML is not yet implemented"-    | json                       =  fail "Rendering expression trees to JSON is not implemented"-    | verbose >= DebugInfo       =  liftIO $ putStr $ PS.ppShow $ stripAnnotation expr-    | cache , Just path <- mpath =  liftIO $ writeCache (addExtension (dropExtension path) "nixc") expr-    | parseOnly                  =  void $ liftIO $ Exc.evaluate $ Deep.force expr+        | tracing                       -> evaluateExprWithEvaluator nixTracingEvalExprLoc expr+        | Just path <- reduce           -> evaluateExprWithEvaluator (reduction path . coerce) expr+        | null arg || null argstr       -> evaluateExprWithEvaluator nixEvalExprLoc expr+        | otherwise                     -> processResult printer <=< nixEvalExprLoc (coerce mpath) $ expr+    | xml                        = fail "Rendering expression trees to XML is not yet implemented"+    | json                       = fail "Rendering expression trees to JSON is not implemented"+    | verbose >= DebugInfo       =  liftIO . putStr . ppShow . stripAnnotation $ expr+    | cache , Just path <- mpath =  liftIO . writeCache (replaceExtension path "nixc") $ expr+    | parseOnly                  =  void . liftIO . Exception.evaluate . force $ expr     | otherwise                  =-      liftIO $+      liftIO .         renderIO           stdout           . layoutPretty (LayoutOptions $ AvailablePerLine 80 0.4)@@ -155,19 +171,31 @@           . stripAnnotation           $ expr    where+    evaluateExprWithEvaluator evaluator = evaluateExpression (coerce mpath) evaluator printer+     printer       | finder    = findAttrs <=< fromValue @(AttrSet (StdValue (StandardT (StdIdT IO))))-      | xml       = liftIO . Text.putStrLn . stringIgnoreContext . toXML <=< normalForm-      -- 2021-05-27: NOTE: With naive fix of the #941-      -- This is overall a naive printer implementation, as options should interact/respect one another.-      -- A nice question: "Should respect one another to what degree?": Go full combinator way, for which-      -- old Nix CLI is nototrious for (and that would mean to reimplement the old Nix CLI),-      -- OR: https://github.com/haskell-nix/hnix/issues/172 and have some sane standart/default behaviour for (most) keys.-      | json      = liftIO . Text.putStrLn . stringIgnoreContext         <=< nvalueToJSONNixString <=< normalForm-      | strict    = liftIO . print         . prettyNValue                <=< normalForm-      | values    = liftIO . print         . prettyNValueProv            <=< removeEffects-      | otherwise = liftIO . print         . prettyNValue                <=< removeEffects+      | otherwise = printer'      where+      printer'+        | xml       = go (stringIgnoreContext . toXML)                     normalForm+        -- 2021-05-27: NOTE: With naive fix of the #941+        -- This is overall a naive printer implementation, as options should interact/respect one another.+        -- A nice question: "Should respect one another to what degree?": Go full combinator way, for which+        -- old Nix CLI is nototrious for (and that would mean to reimplement the old Nix CLI),+        -- OR: https://github.com/haskell-nix/hnix/issues/172 and have some sane standart/default behaviour for (most) keys.+        | json      = go (stringIgnoreContext . mempty . nvalueToJSONNixString) normalForm+        | strict    = go (show . prettyNValue)                             normalForm+        | values    = go (show . prettyNValueProv)                         removeEffects+        | otherwise = go (show . prettyNValue)                             removeEffects+       where+        go+          :: (b -> Text)+          -> (a -> StandardT (StdIdT IO) b)+          -> a+          -> StandardT (StdIdT IO) ()+        go g f = liftIO . Text.putStrLn . g <=< f+       findAttrs         :: AttrSet (StdValue (StandardT (StdIdT IO)))         -> StandardT (StdIdT IO) ()@@ -200,7 +228,7 @@                     (pure . pure . Free)                     nv                 )-                (sortWith fst $ M.toList s)+                (sortWith fst $ M.toList $ M.mapKeys coerce s)             traverse_               (\ (k, mv) ->                 do@@ -212,10 +240,10 @@                       liftIO $ Text.putStrLn path                       when descend $                         maybe-                          pass+                          stub                           (\case-                            NVSet s' _ -> go (path <> ".") s'-                            _          -> pass+                            NVSet _ s' -> go (path <> ".") s'+                            _          -> stub                           )                           mv               )@@ -239,10 +267,10 @@             _                              -> (True , True )            forceEntry-            :: MonadValue a (Fix1T StandardTF (StdIdT IO))+            :: MonadValue a (StandardT (StdIdT IO))             => Text             -> a-            -> Fix1T StandardTF (StdIdT IO) (Maybe a)+            -> StandardT (StdIdT IO) (Maybe a)           forceEntry k v =             catch               (pure <$> demand v)@@ -259,24 +287,24 @@                   pure Nothing               ) -  reduction path mp x =+  reduction path mpathToContext annExpr =     do       eres <--        Nix.withNixContext-          mp-          (Nix.reducingEvalExpr-            Eval.evalContent-            mp-            x+        withNixContext+          mpathToContext+          (reducingEvalExpr+            evalContent+            mpathToContext+            annExpr           )       handleReduced path eres    handleReduced     :: (MonadThrow m, MonadIO m)-    => FilePath+    => Path     -> (NExprLoc, Either SomeException (NValue t f m))     -> m (NValue t f m)-  handleReduced path (expr', eres) =+  handleReduced (coerce -> path) (expr', eres) =     do       liftIO $         do
main/Repl.hs view
@@ -7,22 +7,19 @@    directory for more details. -} -{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# language MultiWayIf #-}  module Repl   ( main   , main'   ) where -import           Nix                     hiding ( exec-                                                , try-                                                )+import           Prelude                 hiding ( state )+import           Nix                     hiding ( exec ) import           Nix.Scope-import           Nix.Utils import           Nix.Value.Monad                ( demand ) -import qualified Data.HashMap.Lazy+import qualified Data.HashMap.Lazy           as M import           Data.Char                      ( isSpace ) import           Data.List                      ( dropWhileEnd ) import qualified Data.Text                   as Text@@ -71,7 +68,7 @@     evalStateT       (evalRepl         banner-        (cmd . toText)+        (cmd . fromString)         options         (pure commandPrefix)         (pure "paste")@@ -99,28 +96,28 @@    rcFile =     do-      f <- liftIO $ Text.readFile ".hnixrc" `catch` handleMissing+      f <- liftIO $ readFile ".hnixrc" `catch` handleMissing        traverse_         (\case           (prefixedCommand : xs) | Text.head prefixedCommand == commandPrefix ->             do               let-                arguments = Text.unwords xs+                arguments = unwords xs                 command = Text.tail prefixedCommand               optMatcher command options arguments-          x -> cmd $ Text.unwords x+          x -> cmd $ unwords x         )-        (Text.words <$> lines f)+        (words <$> lines f)    handleMissing e-    | Error.isDoesNotExistError e = pure ""-    | otherwise = throwIO e+    | Error.isDoesNotExistError e = pure mempty+    | otherwise = throwM e    -- Replicated and slightly adjusted `optMatcher` from `System.Console.Repline`   -- which doesn't export it.-  -- * @MonadIO m@ instead of @MonadHaskeline m@-  -- * @putStrLn@ instead of @outputStrLn@+  --  * @MonadIO m@ instead of @MonadHaskeline m@+  --  * @putStrLn@ instead of @outputStrLn@   optMatcher :: MonadIO m              => Text              -> Console.Options m@@ -128,16 +125,16 @@              -> m ()   optMatcher s [] _ = liftIO $ Text.putStrLn $ "No such command :" <> s   optMatcher s ((x, m) : xs) args-    | s `Text.isPrefixOf` toText x = m $ toString args+    | s `Text.isPrefixOf` fromString x = m $ toString args     | otherwise = optMatcher s xs args   -- * Types  data IState t f m = IState-  { replIt  :: Maybe NExprLoc          -- ^ Last expression entered-  , replCtx :: AttrSet (NValue t f m)  -- ^ Value environment-  , replCfg :: ReplConfig              -- ^ REPL configuration+  { replIt  :: Maybe NExprLoc        -- ^ Last expression entered+  , replCtx :: Scope (NValue t f m)  -- ^ Scope. Value environment.+  , replCfg :: ReplConfig            -- ^ REPL configuration   } deriving (Eq, Show)  data ReplConfig = ReplConfig@@ -159,14 +156,17 @@    builtins <- evalText "builtins" -  opts :: Nix.Options <- asks (view hasLens)+  let+    scope = coerce $+      M.fromList $+      ("builtins", builtins) : fmap ("input",) (maybeToList mIni) +  opts :: Nix.Options <- asks $ view hasLens+   pure $     IState       Nothing-      (Data.HashMap.Lazy.fromList $-        ("builtins", builtins) : fmap ("input",) (maybeToList mIni)-      )+      scope       defReplConfig         { cfgStrict = strict opts         , cfgValues = values opts@@ -192,9 +192,9 @@   -> Repl e t f m (Maybe (NValue t f m)) exec update source = do   -- Get the current interpreter state-  st <- get+  state <- get -  when (cfgDebug $ replCfg st) $ liftIO $ print st+  when (cfgDebug $ replCfg state) $ liftIO $ print state    -- Parser ( returns AST as `NExprLoc` )   case parseExprOrBinding source of@@ -211,7 +211,7 @@       -- let tyctx' = inferTop mempty [("repl", stripAnnotation expr)]       -- liftIO $ print tyctx' -      mVal <- lift $ lift $ try $ pushScope (replCtx st) (evalExprLoc expr)+      mVal <- lift $ lift $ try $ pushScope (replCtx state) (evalExprLoc expr)        either         (\ (NixException frames) -> do@@ -221,12 +221,12 @@           -- Update the interpreter state           when (update && isBinding) $ do             -- Set `replIt` to last entered expression-            put st { replIt = pure expr }+            put state { replIt = pure expr }              -- If the result value is a set, update our context with it             case val of-              NVSet xs _ -> put st { replCtx = xs <> replCtx st }-              _          -> pass+              NVSet _ (coerce -> scope) -> put state { replCtx = scope <> replCtx state }+              _          -> stub            pure $ pure val         )@@ -248,7 +248,7 @@         (parseNixTextLoc i)      toAttrSet i =-      "{" <> i <> bool ";" mempty (Text.isSuffixOf ";" i) <> "}"+      "{" <> i <> whenFalse ";" (Text.isSuffixOf ";" i) <> "}"  cmd   :: (MonadNix e t f m, MonadIO m)@@ -258,7 +258,7 @@   do     mVal <- exec True source     maybe-      pass+      stub       printValue       mVal @@ -267,11 +267,15 @@            -> Repl e t f m () printValue val = do   cfg <- replCfg <$> get+  let+    g :: MonadIO m => Doc ann0 -> m ()+    g = liftIO . print+   lift $ lift $     (if-      | cfgStrict cfg -> liftIO . print . prettyNValue     <=< normalForm-      | cfgValues cfg -> liftIO . print . prettyNValueProv <=< removeEffects-      | otherwise     -> liftIO . print . prettyNValue     <=< removeEffects+      | cfgStrict cfg -> g . prettyNValue     <=< normalForm+      | cfgValues cfg -> g . prettyNValueProv <=< removeEffects+      | otherwise     -> g . prettyNValue     <=< removeEffects     ) val  @@ -281,26 +285,31 @@ browse :: (MonadNix e t f m, MonadIO m)        => Text        -> Repl e t f m ()-browse _ = do-  st <- get-  for_ (Data.HashMap.Lazy.toList $ replCtx st) $ \(k, v) -> do-    liftIO $ Text.putStr $ k <> " = "-    printValue v+browse _ =+  do+    state <- get+    traverse_+      (\(k, v) ->+        do+          liftIO $ Text.putStr $ coerce k <> " = "+          printValue v+      )+      (M.toList $ coerce $ replCtx state)  -- | @:load@ command load   :: (MonadNix e t f m, MonadIO m)   -- This one does I String -> O String pretty fast, it is ugly to double marshall here.-  => String+  => Path   -> Repl e t f m ()-load args =+load path =   do-    contents <- liftIO $-      Text.readFile $-       trim args+    contents <- liftIO $ readFile $+       trim path     void $ exec True contents  where-  trim = dropWhileEnd isSpace . dropWhile isSpace+  trim :: Path -> Path+  trim = coerce . dropWhileEnd isSpace . dropWhile isSpace . coerce  -- | @:type@ command typeof@@ -308,12 +317,12 @@   => Text   -> Repl e t f m () typeof args = do-  st <- get+  state <- get   mVal <-     maybe       (exec False line)       (pure . pure)-      (Data.HashMap.Lazy.lookup line (replCtx st))+      (M.lookup (coerce line) (coerce $ replCtx state))    traverse_ printValueType mVal @@ -332,12 +341,14 @@ -- | @:set@ command setConfig :: (MonadNix e t f m, MonadIO m) => Text -> Repl e t f m () setConfig args =-  case Text.words args of-    []       -> liftIO $ Text.putStrLn "No option to set specified"-    (x:_xs)  ->+  list+    (liftIO $ Text.putStrLn "No option to set specified")+    (\ (x:_xs)  ->       case filter ((==x) . helpSetOptionName) helpSetOptions of         [opt] -> modify (\s -> s { replCfg = helpSetOptionFunction opt (replCfg s) })         _     -> liftIO $ Text.putStrLn "No such option"+    )+    $ words args   -- * Interactive Shell@@ -345,8 +356,7 @@ -- | Prefix tab completer defaultMatcher :: MonadIO m => [(String, CompletionFunc m)] defaultMatcher =-  [ (":load", Console.fileCompleter)-  ]+  one (":load", Console.fileCompleter)  completion   :: (MonadNix e t f m, MonadIO m)@@ -381,9 +391,9 @@     listFiles word    -- Attributes of sets in REPL context-  | var : subFields <- Text.split (== '.') (toText word) , not $ null subFields =+  | var : subFields <- Text.split (== '.') (fromString word) , not $ null subFields =     do-      s <- get+      state <- get       maybe         stub         (\ binding ->@@ -396,18 +406,24 @@                     candidates                   )         )-        (Data.HashMap.Lazy.lookup var (replCtx s))+        (M.lookup (coerce var) $ coerce $ replCtx state)    -- Builtins, context variables   | otherwise =     do-      s <- get-      let contextKeys = Data.HashMap.Lazy.keys (replCtx s)-          (Just (NVSet builtins _)) = Data.HashMap.Lazy.lookup "builtins" (replCtx s)-          shortBuiltins = Data.HashMap.Lazy.keys builtins+      state <- get+      let+          scopeHashMap :: HashMap VarName (NValue t f m)+          scopeHashMap = coerce $ replCtx state+          contextKeys :: [VarName]+          contextKeys = M.keys scopeHashMap+          builtins :: AttrSet (NValue t f m)+          (Just (NVSet _ builtins)) = M.lookup "builtins" scopeHashMap+          shortBuiltins :: [VarName]+          shortBuiltins = M.keys builtins        pure $ listCompletion $ toString <$>-        ["__includes"]+        one "__includes"           <> contextKeys           <> shortBuiltins @@ -423,7 +439,7 @@       -> m [Text]     algebraicComplete subFields val =       let-        keys = fmap ("." <>) . Data.HashMap.Lazy.keys+        keys = fmap ("." <>) . M.keys          withMap m =           case subFields of@@ -437,10 +453,10 @@                    (("." <> f) <>)                    . algebraicComplete fs <=< demand                 )-                (Data.HashMap.Lazy.lookup f m)+                (M.lookup (coerce f) m)       in       case val of-        NVSet xs _ -> withMap xs+        NVSet _ xs -> withMap (M.mapKeys coerce xs)         _          -> stub  -- | HelpOption inspired by Dhall Repl@@ -458,44 +474,44 @@ helpOptions =   [ HelpOption       "help"-      ""+      mempty       "Print help text"-      (help helpOptions . toText)+      (help helpOptions . fromString)   , HelpOption       "paste"-      ""+      mempty       "Enter multi-line mode"       (error "Unreachable")   , HelpOption       "load"       "FILENAME"       "Load .nix file into scope"-      load+      (load . fromString)   , HelpOption       "browse"-      ""+      mempty       "Browse bindings in interpreter context"-      (browse . toText)+      (browse . fromString)   , HelpOption       "type"       "EXPRESSION"       "Evaluate expression or binding from context and print the type of the result value"-      (typeof . toText)+      (typeof . fromString)   , HelpOption       "quit"-      ""+      mempty       "Quit interpreter"       quit   , HelpOption       "set"-      ""+      mempty       ("Set REPL option"         <> Prettyprinter.line         <> "Available options:"         <> Prettyprinter.line         <> renderSetOptions helpSetOptions       )-      (setConfig . toText)+      (setConfig . fromString)   ]  -- | Options for :set@@ -510,32 +526,32 @@ helpSetOptions =   [ HelpSetOption       "strict"-      ""+      mempty       "Enable strict evaluation of REPL expressions"       (\x -> x { cfgStrict = True})   , HelpSetOption       "lazy"-      ""+      mempty       "Disable strict evaluation of REPL expressions"       (\x -> x { cfgStrict = False})   , HelpSetOption       "values"-      ""+      mempty       "Enable printing of value provenance information"       (\x -> x { cfgValues = True})   , HelpSetOption       "novalues"-      ""+      mempty       "Disable printing of value provenance information"       (\x -> x { cfgValues = False})   , HelpSetOption       "debug"-      ""+      mempty       "Enable printing of REPL debug information"       (\x -> x { cfgDebug = True})   , HelpSetOption       "nodebug"-      ""+      mempty       "Disable REPL debugging"       (\x -> x { cfgDebug = False})   ]
src/Nix.hs view
@@ -1,10 +1,10 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ViewPatterns #-}  module Nix   ( module Nix.Cache   , module Nix.Exec-  , module Nix.Expr+  , module Nix.Expr.Types+  , module Nix.Expr.Shorthands+  , module Nix.Expr.Types.Annotated   , module Nix.Frames   , module Nix.Render.Frame   , module Nix.Normal@@ -35,7 +35,9 @@ import           Nix.Cache import qualified Nix.Eval                      as Eval import           Nix.Exec-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Shorthands+import           Nix.Expr.Types.Annotated import           Nix.Frames import           Nix.String import           Nix.Normal@@ -45,7 +47,6 @@ import           Nix.Reduce import           Nix.Render.Frame import           Nix.Thunk-import           Nix.Utils import           Nix.Value import           Nix.Value.Monad import           Nix.XML@@ -57,7 +58,7 @@   :: (MonadNix e t f m, Has e Options, Functor g)   => Transform g (m a)   -> Alg g (m a)-  -> Maybe FilePath+  -> Maybe Path   -> Fix g   -> m a nixEval transform alg mpath = withNixContext mpath . adi transform alg@@ -65,7 +66,7 @@ -- | Evaluate a nix expression in the default context nixEvalExpr   :: (MonadNix e t f m, Has e Options)-  => Maybe FilePath+  => Maybe Path   -> NExpr   -> m (NValue t f m) nixEvalExpr = nixEval id Eval.eval@@ -74,7 +75,7 @@ nixEvalExprLoc   :: forall e t f m    . (MonadNix e t f m, Has e Options)-  => Maybe FilePath+  => Maybe Path   -> NExprLoc   -> m (NValue t f m) nixEvalExprLoc =@@ -89,22 +90,22 @@ --   context. nixTracingEvalExprLoc   :: (MonadNix e t f m, Has e Options, MonadIO m, Alternative m)-  => Maybe FilePath+  => Maybe Path   -> NExprLoc   -> m (NValue t f m) nixTracingEvalExprLoc mpath = withNixContext mpath . evalExprLoc  evaluateExpression   :: (MonadNix e t f m, Has e Options)-  => Maybe FilePath-  -> (Maybe FilePath -> NExprLoc -> m (NValue t f m))+  => Maybe Path+  -> (Maybe Path -> NExprLoc -> m (NValue t f m))   -> (NValue t f m -> m a)   -> NExprLoc   -> m a evaluateExpression mpath evaluator handler expr =   do     opts :: Options <- asks $ view hasLens-    args <-+    (coerce -> args) <-       (traverse . traverse)         eval'         $  (second parseArg <$> arg    opts)@@ -137,23 +138,23 @@   opts :: Options <- asks $ view hasLens   maybe     (h val)-    (\ (Text.splitOn "." -> keys) -> processKeys keys val)+    (\ (coerce . Text.splitOn "." -> keys) -> processKeys keys val)     (attr opts)  where-  processKeys :: [Text] -> NValue t f m -> m a+  processKeys :: [VarName] -> NValue t f m -> m a   processKeys kys v =     list       (h v)-      (\ (k : ks) ->+      (\ ((k : ks) :: [VarName]) ->         do           v' <- demand v           case (k, v') of-            (Text.decimal -> Right (n,""), NVList xs) -> processKeys ks $ xs !! n-            (_,         NVSet xs _) ->+            (Text.decimal . coerce -> Right (n,""), NVList xs) -> processKeys ks $ xs !! n+            (_,         NVSet _ xs) ->               maybe-                (errorWithoutStackTrace $ toString $ "Set does not contain key '" <> k <> "'")+                (errorWithoutStackTrace $ "Set does not contain key ''" <> show k <> "''.")                 (processKeys ks)                 (M.lookup k xs)-            (_, _) -> errorWithoutStackTrace $ toString $ "Expected a set or list for selector '" <> k <> "', but got: " <> show v+            (_, _) -> errorWithoutStackTrace $ "Expected a set or list for selector '" <> show k <> "', but got: " <> show v       )       kys
src/Nix/Atoms.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE CPP            #-}-{-# LANGUAGE DeriveAnyClass #-}+{-# language CPP            #-}+{-# language DeriveAnyClass #-}  module Nix.Atoms where @@ -11,6 +11,7 @@ import           Data.Aeson.Types               ( FromJSON                                                 , ToJSON                                                 )+--  2021-08-01: NOTE: Check the order efficience of NAtom constructors.  -- | Atoms are values that evaluate to themselves. -- In other words - this is a constructors that are literals in Nix.
src/Nix/Builtins.hs view
@@ -1,20 +1,17 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE MonoLocalBinds #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE PackageImports #-}-{-# LANGUAGE PartialTypeSignatures #-}-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE PackageImports #-} -- 2021-07-05: Due to hashing Haskell IT system situation, in HNix we currently ended-up with 2 hash package dependencies @{hashing, cryptonite}@+{-# language CPP #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language FunctionalDependencies #-}+{-# language KindSignatures #-}+{-# language MonoLocalBinds #-}+{-# language MultiWayIf #-}+{-# language PartialTypeSignatures #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}+{-# language UndecidableInstances #-}+{-# language PackageImports #-} -- 2021-07-05: Due to hashing Haskell IT system situation, in HNix we currently ended-up with 2 hash package dependencies @{hashing, cryptonite}@ -{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# options_ghc -fno-warn-name-shadowing #-}  -- | Code that implements Nix builtins. Lists the functions that are built into the Nix expression evaluator. Some built-ins (aka `derivation`), are always in the scope, so they can be accessed by the name. To keap the namespace clean, most built-ins are inside the `builtins` scope - a set that contains all what is a built-in. module Nix.Builtins@@ -24,8 +21,7 @@ where  -import           Prelude                 hiding ( traceM )-import           Nix.Utils+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import           Control.Comonad                ( Comonad ) import           Control.Monad                  ( foldM ) import           Control.Monad.Catch            ( MonadCatch(catch) )@@ -53,9 +49,9 @@ import           Data.Scientific import qualified Data.Set                      as S import qualified Data.Text                     as Text-import qualified Data.Text.Lazy                as LazyText+import           Data.Text.Read                 ( decimal ) import qualified Data.Text.Lazy.Builder        as Builder-import           Data.These                     ( fromThese )+import           Data.These                     ( fromThese, These ) import qualified Data.Time.Clock.POSIX         as Time import qualified Data.Vector                   as V import           NeatInterpolation              ( text )@@ -65,7 +61,6 @@ import           Nix.Effects.Basic              ( fetchTarball ) import           Nix.Exec import           Nix.Expr.Types-import           Nix.Expr.Types.Annotated import qualified Nix.Eval                      as Eval import           Nix.Frames import           Nix.Json@@ -81,11 +76,11 @@ import           Nix.Value.Monad import           Nix.XML import           System.Nix.Base32             as Base32-import           System.FilePath-import           System.Posix.Files             ( isRegularFile+import           System.PosixCompat.Files       ( isRegularFile                                                 , isDirectory                                                 , isSymbolicLink                                                 )+import qualified Text.Show import           Text.Regex.TDFA                ( Regex                                                 , makeRegex                                                 , matchOnceText@@ -101,13 +96,13 @@  -- ** Nix Builtins Haskell type level -newtype Prim m a = Prim { runPrim :: m a }+newtype Prim m a = Prim (m a)  data BuiltinType = Normal | TopLevel data Builtin v =   Builtin     { _kind   :: BuiltinType-    , mapping :: (Text, v)+    , mapping :: (VarName, v)     }  -- *** @class ToBuiltin@ and its instances@@ -121,7 +116,7 @@   , ToValue a m (NValue t f m)   )   => ToBuiltin t f m (Prim m a) where-  toBuiltin _ p = toValue =<< runPrim p+  toBuiltin _ p = toValue @a @m =<< coerce p  instance   ( MonadNix e t f m@@ -130,7 +125,7 @@   )   => ToBuiltin t f m (a -> b) where   toBuiltin name f =-    pure $ nvBuiltin name $ toBuiltin name . f <=< fromValue . Deeper+    pure $ nvBuiltin (coerce name) $ toBuiltin name . f <=< fromValue . Deeper  -- *** @WValue@ closure wrapper to have @Ord@ @@ -174,11 +169,28 @@   -> NValue t f m mkNVBool = nvConstant . NBool +data NixPathEntryType+  = PathEntryPath+  | PathEntryURI+ deriving (Show, Eq)++-- | @NIX_PATH@ is colon-separated, but can also contain URLs, which have a colon+-- (i.e. @https://...@)+uriAwareSplit :: Text -> [(Text, NixPathEntryType)]+uriAwareSplit txt =+  case Text.break (== ':') txt of+    (e1, e2)+      | Text.null e2                              -> one (e1, PathEntryPath)+      | "://" `Text.isPrefixOf` e2      ->+        let ((suffix, _) : path) = uriAwareSplit (Text.drop 3 e2) in+        (e1 <> "://" <> suffix, PathEntryURI) : path+      | otherwise                                 -> (e1, PathEntryPath) : uriAwareSplit (Text.drop 1 e2)+ foldNixPath   :: forall e t f m r    . MonadNix e t f m   => r-  -> (FilePath -> Maybe Text -> NixPathEntryType -> r -> m r)+  -> (Path -> Maybe Text -> NixPathEntryType -> r -> m r)   -> m r foldNixPath z f =   do@@ -193,36 +205,36 @@     dataDir  <-       maybe         getDataDir-        (pure . toString)+        (pure . coerce . toString)         mDataDir      foldrM       go       z       $ (fromInclude . stringIgnoreContext <$> dirs)-        <> maybe-            mempty-            uriAwareSplit-            mPath-        <> [ fromInclude $ "nix=" <> toText dataDir <> "/nix/corepkgs" ]+        <> uriAwareSplit `whenJust` mPath+        <> one (fromInclude $ "nix=" <> fromString (coerce dataDir) <> "/nix/corepkgs")  where -  fromInclude x = (x, ) $-    bool-      PathEntryPath-      PathEntryURI-      ("://" `Text.isInfixOf` x)+  fromInclude :: Text -> (Text, NixPathEntryType)+  fromInclude x =+    (x, ) $+      bool+        PathEntryPath+        PathEntryURI+        ("://" `Text.isInfixOf` x) +  go :: (Text, NixPathEntryType) -> r -> m r   go (x, ty) rest =     case Text.splitOn "=" x of-      [p] -> f (toString p) mempty ty rest-      [n, p] -> f (toString p) (pure n) ty rest+      [p] -> f (coerce $ toString p) mempty ty rest+      [n, p] -> f (coerce $ toString p) (pure n) ty rest       _ -> throwError $ ErrorCall $ "Unexpected entry in NIX_PATH: " <> show x -attrsetGet :: MonadNix e t f m => Text -> AttrSet (NValue t f m) -> m (NValue t f m)+attrsetGet :: MonadNix e t f m => VarName -> AttrSet (NValue t f m) -> m (NValue t f m) attrsetGet k s =   maybe-    (throwError $ ErrorCall $ "Attribute '" <> toString k <> "' required")+    (throwError $ ErrorCall $ toString @Text $ "Attribute '" <> coerce k <> "' required")     pure     (M.lookup k s) @@ -230,77 +242,82 @@   = VersionComponentPre -- ^ The string "pre"   | VersionComponentString !Text -- ^ A string other than "pre"   | VersionComponentNumber !Integer -- ^ A number-  deriving (Show, Read, Eq, Ord)--versionComponentToString :: VersionComponent -> Text-versionComponentToString =-  \case-    VersionComponentPre      -> "pre"-    VersionComponentString s -> s-    VersionComponentNumber n -> show n+  deriving (Read, Eq, Ord) --- | Based on https://github.com/NixOS/nix/blob/4ee4fda521137fed6af0446948b3877e0c5db803/src/libexpr/names.cc#L44-versionComponentSeparators :: String-versionComponentSeparators = ".-"+instance Show VersionComponent where+  show =+    \case+      VersionComponentPre      -> "pre"+      VersionComponentString s -> show s+      VersionComponentNumber n -> show n  splitVersion :: Text -> [VersionComponent] splitVersion s =-  case Text.uncons s of-    Nothing -> mempty-    Just (h, t)+ whenJust+   (\ (x, xs) -> if+      | isRight eDigitsPart ->+          either+            (\ e -> error $ "splitVersion: did hit impossible: '" <> toText e <> "' while parsing '" <> s <> "'.")+            (\ res ->+              one (VersionComponentNumber $ fst res)+              <> splitVersion (snd res)+            )+            eDigitsPart -      | h `elem` versionComponentSeparators -> splitVersion t+      | x `elem` separators -> splitVersion xs -      | isDigit h ->-        let (digits, rest) = Text.span isDigit s-        in-        VersionComponentNumber-            (fromMaybe (error $ "splitVersion: couldn't parse " <> show digits) $ readMaybe $ toString digits) : splitVersion rest+      | otherwise -> one charsPart <> splitVersion rest2+  )+  (Text.uncons s)+ where+  -- | Based on https://github.com/NixOS/nix/blob/4ee4fda521137fed6af0446948b3877e0c5db803/src/libexpr/names.cc#L44+  separators :: String+  separators = ".-" -      | otherwise ->-        let-          (chars, rest) =-            Text.span-              (\c -> not $ isDigit c || c `elem` versionComponentSeparators)-              s-          thisComponent =-            case chars of-              "pre" -> VersionComponentPre-              x     -> VersionComponentString x-        in-        thisComponent : splitVersion rest+  eDigitsPart :: Either String (Integer, Text)+  eDigitsPart = decimal @Integer $ s +  (charsSpan, rest2) =+    Text.span+      (\c -> not $ isDigit c || c `elem` separators)+      s++  charsPart :: VersionComponent+  charsPart =+    case charsSpan of+      "pre" -> VersionComponentPre+      xs'   -> VersionComponentString xs'++ compareVersions :: Text -> Text -> Ordering compareVersions s1 s2 =-  mconcat $-    alignWith-      f-      (splitVersion s1)-      (splitVersion s2)+  fold $ (alignWith cmp `on` splitVersion) s1 s2  where-  z = VersionComponentString ""-  f = uncurry compare . fromThese z z+  cmp :: These VersionComponent VersionComponent -> Ordering+  cmp = uncurry compare . join fromThese (VersionComponentString mempty)  splitDrvName :: Text -> (Text, Text) splitDrvName s =-  let-    sep    = "-"-    pieces = Text.splitOn sep s-    isFirstVersionPiece p =-      case Text.uncons p of-        Just (h, _) -> isDigit h-        _           -> False-    -- Like 'break', but always puts the first item into the first result-    -- list-    breakAfterFirstItem :: (a -> Bool) -> [a] -> ([a], [a])-    breakAfterFirstItem f =-      list-        (mempty, mempty)-        (\ (h : t) -> let (a, b) = break f t in (h : a, b))-    (namePieces, versionPieces) =-      breakAfterFirstItem isFirstVersionPiece pieces-  in-  (Text.intercalate sep namePieces, Text.intercalate sep versionPieces)+  both (Text.intercalate sep) (namePieces, versionPieces)+ where+  sep    = "-"+  pieces :: [Text]+  pieces = Text.splitOn sep s+  isFirstVersionPiece :: Text -> Bool+  isFirstVersionPiece p =+    maybe+      False+      (isDigit . fst)+      (Text.uncons p)+  -- Like 'break', but always puts the first item into the first result+  -- list+  breakAfterFirstItem :: (a -> Bool) -> [a] -> ([a], [a])+  breakAfterFirstItem f =+    list+      mempty+      (\ (h : t) -> let (a, b) = break f t in (h : a, b))+  (namePieces, versionPieces) =+    breakAfterFirstItem isFirstVersionPiece pieces  splitMatches   :: forall e t f m@@ -309,7 +326,7 @@   -> [[(ByteString, (Int, Int))]]   -> ByteString   -> [NValue t f m]-splitMatches _ [] haystack = [thunkStr haystack]+splitMatches _ [] haystack = one $ thunkStr haystack splitMatches _ ([] : _) _ =   fail "Fail in splitMatches: this should never happen!" splitMatches numDropped (((_, (start, len)) : captures) : mts) haystack =@@ -319,7 +336,9 @@  where   relStart       = max 0 start - numDropped   (before, rest) = B.splitAt relStart haystack+  caps :: NValue t f m   caps           = nvList (f <$> captures)+  f :: (ByteString, (Int, b)) -> NValue t f m   f (a, (s, _))  =     bool       nvNull@@ -334,23 +353,18 @@    . (MonadNix e t f m, FromValue a m (NValue t f m))   => NValue t f m   -> m (NValue t f m)-hasKind nv =-  do-    v <- fromValueMay nv--    toValue $-      case v of-        Just (_ :: a) -> True-        _             -> False+hasKind =+  inHaskMay+    (isJust @a)  -absolutePathFromValue :: MonadNix e t f m => NValue t f m -> m FilePath+absolutePathFromValue :: MonadNix e t f m => NValue t f m -> m Path absolutePathFromValue =   \case     NVStr ns ->       do         let-          path = toString $ stringIgnoreContext ns+          path = coerce . toString $ stringIgnoreContext ns          unless (isAbsolute path) $ throwError $ ErrorCall $ "string " <> show path <> " doesn't represent an absolute path"         pure path@@ -368,7 +382,7 @@  instance Convertible e t f m => ToValue FileType m (NValue t f m) where   toValue =-    toValue . makeNixStringWithoutContext .+    toValue . mkNixStringWithoutContext .       \case         FileTypeRegular   -> "regular" :: Text         FileTypeDirectory -> "directory"@@ -411,29 +425,26 @@     [|| expr ||]   ) -nixPathNix :: MonadNix e t f m => m (NValue t f m)+nixPathNix :: forall e t f m . MonadNix e t f m => m (NValue t f m) nixPathNix =   fmap     nvList-    (foldNixPath mempty $-      \p mn ty rest ->-        pure $-          pure-            (nvSet-              mempty-              (M.fromList-                [case ty of-                  PathEntryPath -> ("path", nvPath p)-                  PathEntryURI  -> ( "uri", mkNvStr p)+    $ foldNixPath mempty $+        \p mn ty rest ->+          pure $+            pure+              (nvSet+                mempty+                (M.fromList+                  [case ty of+                    PathEntryPath -> ("path", nvPath  p)+                    PathEntryURI  -> ( "uri", nvStrWithoutContext $ fromString $ coerce p) -                , ( "prefix", mkNvStr $ toString $ fromMaybe "" mn)-                ]+                  , ( "prefix", nvStrWithoutContext $ maybeToMonoid mn)+                  ]+                )               )-            )-          <> rest-    )- where-  mkNvStr = nvStrWithoutContext . toText+            <> rest  toStringNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m) toStringNix = toValue <=< coerceToString callFunc DontCopyToStore CoerceAny@@ -446,13 +457,13 @@   -> m (NValue t f m) hasAttrNix x y =   do-    key <- fromStringNoContext =<< fromValue x-    (aset, _) <- fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) y+    (coerce -> key) <- fromStringNoContext =<< fromValue x+    (aset, _) <- fromValue @(AttrSet (NValue t f m), PositionSet) y      toValue $ M.member key aset  hasContextNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)-hasContextNix = toValue . stringHasContext <=< fromValue+hasContextNix = inHask stringHasContext  getAttrNix   :: forall e t f m@@ -462,8 +473,8 @@   -> m (NValue t f m) getAttrNix x y =   do-    key <- fromStringNoContext =<< fromValue x-    (aset, _) <- fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) y+    (coerce -> key) <- fromStringNoContext =<< fromValue x+    (aset, _) <- fromValue @(AttrSet (NValue t f m), PositionSet) y      attrsetGet key aset @@ -479,18 +490,18 @@     y <- demand nvY      case (x, y) of-      (NVStr ns, NVSet _ apos) ->+      (NVStr ns, NVSet apos _) ->         maybe           (pure nvNull)           toValue-          (M.lookup (stringIgnoreContext ns) apos)+          (M.lookup @VarName (coerce $ stringIgnoreContext ns) apos)       _xy -> throwError $ ErrorCall $ "Invalid types for builtins.unsafeGetAttrPosNix: " <> show _xy  -- This function is a bit special in that it doesn't care about the contents -- of the list. lengthNix   :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)-lengthNix = toValue . (length :: [NValue t f m] -> Int) <=< fromValue+lengthNix = inHask (length :: [NValue t f m] -> Int)  addNix   :: MonadNix e t f m@@ -587,7 +598,7 @@ headNix =   maybe     (throwError $ ErrorCall "builtins.head: empty list")-    (pure)+    pure   . viaNonEmpty head <=< fromValue @[NValue t f m]  tailNix :: forall e t f m. MonadNix e t f m => NValue t f m -> m (NValue t f m)@@ -603,7 +614,7 @@     version <- fromStringNoContext =<< fromValue v     pure $       nvList $-        nvStrWithoutContext . versionComponentToString <$>+        nvStrWithoutContext . show <$>           splitVersion version  compareVersionsNix@@ -639,7 +650,7 @@      toValue @(AttrSet (NValue t f m)) $       M.fromList-        [ ( "name" :: Text+        [ ( "name" :: VarName           , mkNVStr name           )         , ( "version"@@ -671,7 +682,7 @@       mkMatch t =         bool           (toValue ()) -- Shorthand for Null-          (toValue $ makeNixStringWithoutContext t)+          (toValue $ mkNixStringWithoutContext t)           (not $ Text.null t)      case matchOnceText re s of@@ -682,8 +693,8 @@             traverse               mkMatch               (case submatches of-                 [] -> []-                 [a] -> [a]+                 [] -> mempty+                 [a] -> one a                  _:xs -> xs -- return only the matched groups, drop the full string               )       _ -> pure nvNull@@ -726,8 +737,10 @@ attrNamesNix   :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m) attrNamesNix =-  (fmap (coerce :: CoerceDeeperToNValue t f m) . toValue . fmap makeNixStringWithoutContext . sort . M.keys)-  <=< fromValue @(AttrSet (NValue t f m))+    coersion . inHask @(AttrSet (NValue t f m))+      (fmap (mkNixStringWithoutContext . coerce) . sort . M.keys)+ where+  coersion = fmap (coerce :: CoerceDeeperToNValue t f m)  attrValuesNix   :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)@@ -737,7 +750,7 @@     toValue $       snd <$>         sortOn-          (fst @Text @(NValue t f m))+          (fst @VarName @(NValue t f m))           (M.toList attrs)  mapNix@@ -747,13 +760,13 @@   -> NValue t f m   -> m (NValue t f m) mapNix f =-  toValue <=<-    traverse-      (defer @(NValue t f m)+  inHaskM @[NValue t f m]+    (traverse+      (defer       . withFrame Debug (ErrorCall "While applying f in map:\n")       . callFunc f       )-      <=< fromValue @[NValue t f m]+    )  mapAttrsNix   :: forall e t f m@@ -770,7 +783,7 @@        applyFunToKeyVal (key, val) =         do-          runFunForKey <- callFunc f $ nvStrWithoutContext key+          runFunForKey <- callFunc f $ nvStrWithoutContext (coerce key)           callFunc runFunForKey val      newVals <-@@ -787,10 +800,11 @@   -> NValue t f m   -> m (NValue t f m) filterNix f =-  toValue <=<-    filterM-      (fromValue <=< callFunc f)-      <=< fromValue+  inHaskM+    (filterM fh)+ where+  fh :: NValue t f m -> m Bool+  fh = fromValue <=< callFunc f  catAttrsNix   :: forall e t f m@@ -805,7 +819,7 @@      nvList . catMaybes <$>       traverse-        (fmap (M.lookup n) . fromValue <=< demand)+        (fmap (M.lookup @VarName $ coerce n) . fromValue <=< demand)         l  baseNameOfNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)@@ -815,7 +829,7 @@     pure $       nvStr $         modifyNixContents-          (toText . takeFileName . toString)+          (fromString . coerce takeFileName . toString)           ns  bitAndNix@@ -829,7 +843,7 @@     a <- fromValue @Integer x     b <- fromValue @Integer y -    toValue (a .&. b)+    toValue $ a .&. b  bitOrNix   :: forall e t f m@@ -842,7 +856,7 @@     a <- fromValue @Integer x     b <- fromValue @Integer y -    toValue (a .|. b)+    toValue $ a .|. b  bitXorNix   :: forall e t f m@@ -855,7 +869,7 @@     a <- fromValue @Integer x     b <- fromValue @Integer y -    toValue (a `xor` b)+    toValue $ a `xor` b  builtinsBuiltinNix   :: forall e t f m@@ -869,16 +883,15 @@     dir <- demand nvdir      case dir of-      NVStr ns -> pure $ nvStr $ modifyNixContents (toText . takeDirectory . toString) ns+      NVStr ns -> pure $ nvStr $ modifyNixContents (fromString . coerce takeDirectory . toString) ns       NVPath path -> pure $ nvPath $ takeDirectory path       v -> throwError $ ErrorCall $ "dirOf: expected string or path, got " <> show v  -- jww (2018-04-28): This should only be a string argument, and not coerced? unsafeDiscardStringContextNix   :: MonadNix e t f m => NValue t f m -> m (NValue t f m)-unsafeDiscardStringContextNix mnv = do-  ns <- fromValue mnv-  toValue $ makeNixStringWithoutContext $ stringIgnoreContext ns+unsafeDiscardStringContextNix =+  inHask (mkNixStringWithoutContext . stringIgnoreContext)  -- | Evaluate `a` to WHNF to collect its topmost effect. seqNix@@ -902,15 +915,18 @@   => NValue t f m   -> NValue t f m   -> m (NValue t f m)-elemNix x = toValue <=< anyMNix (valueEqM x) <=< fromValue+elemNix x = inHaskM (anyMNix $ valueEqM x)  where   anyMNix :: Monad m => (a -> m Bool) -> [a] -> m Bool-  anyMNix _ []       = pure False-  anyMNix p (x : xs) =-    bool-      (anyMNix p xs)-      (pure True)-      =<< p x+  anyMNix p =+    list+      (pure False)+      (\ (x : xss) ->+        bool+          (anyMNix p xss)+          (pure True)+          =<< p x+      )  elemAtNix   :: MonadNix e t f m@@ -954,33 +970,32 @@       do         ss <- fromValue @[NValue t f m] =<< demand startSet         op <- demand operator+        let+          go+            :: Set (WValue t f m)+            -> [NValue t f m]+            -> m (Set (WValue t f m), [NValue t f m])+          go ks []       = pure (ks, mempty)+          go ks (t : ts) =+            do+              v <- demand t+              k <- demand =<< attrsetGet "key" =<< fromValue @(AttrSet (NValue t f m)) v -        toValue @[NValue t f m] =<< snd <$> go op mempty ss- where-  go-    :: NValue t f m-    -> Set (WValue t f m)-    -> [NValue t f m]-    -> m (Set (WValue t f m), [NValue t f m])-  go _  ks []       = pure (ks, mempty)-  go op ks (t : ts) =-    do-      v <- demand t-      k <- demand =<< attrsetGet "key" =<< fromValue @(AttrSet (NValue t f m)) v+              bool+                (do+                  checkComparable k $+                    list+                      k+                      (\ (WValue j:_) -> j)+                      (S.toList ks) -      bool-        (do-          ys <- fromValue @[NValue t f m] =<< callFunc op v-          checkComparable k-            (case S.toList ks of-              []           -> k-              WValue j : _ -> j-            )-          (t :) <<$>> go op (S.insert (WValue k) ks) (ts <> ys)-        )-        (go op ks ts)-        (S.member (WValue k) ks)+                  (<<$>>) (v :) . go (S.insert (WValue k) ks) . (<>) ts =<< fromValue @[NValue t f m] =<< callFunc op v+                )+                (go ks ts)+                (S.member (WValue k) ks) +        toValue @[NValue t f m] =<< snd <$> go mempty ss+ -- | Takes: -- 1. List of strings to match. -- 2. List of strings to replace corresponding match occurance. (arg 1 & 2 lists matched by index)@@ -1021,7 +1036,7 @@         maybePrefixMatch :: Maybe (Text, NixString, Text)         maybePrefixMatch = formMatchReplaceTailInfo <$> find ((`Text.isPrefixOf` input) . fst) fromKeysToValsMap          where-          formMatchReplaceTailInfo = (\(m, r) -> (m, r, Text.drop (Text.length m) input))+          formMatchReplaceTailInfo (m, r) = (m, r, Text.drop (Text.length m) input)            fromKeysToValsMap = zip (stringIgnoreContext <$> fromKeys) toVals @@ -1034,7 +1049,7 @@          --  2021-02-18: NOTE: rly?: toStrict . toLazyText         --  Maybe `text-builder`, `text-show`?-        finish ctx output = makeNixString (LazyText.toStrict $ Builder.toLazyText output) ctx+        finish ctx output = mkNixString (toStrict $ Builder.toLazyText output) ctx          replace (key, replacementNS, unprocessedInput) = replaceWithNixBug unprocessedInput updatedOutput @@ -1080,11 +1095,12 @@   -> m (NValue t f m) removeAttrsNix set v =   do-    (m, p) <- fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) set+    (m, p) <- fromValue @(AttrSet (NValue t f m), PositionSet) set     (nsToRemove :: [NixString]) <- fromValue $ Deeper v-    toRemove <- traverse fromStringNoContext nsToRemove+    (coerce -> toRemove) <- traverse fromStringNoContext nsToRemove     toValue (go m toRemove, go p toRemove)  where+  go :: forall k v . (Eq k, Hashable k) => HashMap k v -> [k] -> HashMap k v   go = foldl' (flip M.delete)  intersectAttrsNix@@ -1095,8 +1111,8 @@   -> m (NValue t f m) intersectAttrsNix set1 set2 =   do-    (s1, p1) <- fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) set1-    (s2, p2) <- fromValue @(AttrSet (NValue t f m), AttrSet SourcePos) set2+    (s1, p1) <- fromValue @(AttrSet (NValue t f m), PositionSet) set1+    (s2, p2) <- fromValue @(AttrSet (NValue t f m), PositionSet) set2      pure $ nvSet (p2 `M.intersection` p1) (s2 `M.intersection` s1) @@ -1110,7 +1126,7 @@         toValue @(AttrSet (NValue t f m)) $ mkNVBool <$>           case p of             Param name     -> one (name, False)-            ParamSet s _ _ -> isJust <$> M.fromList s+            ParamSet _ _ pset -> isJust <$> M.fromList pset       _v -> throwError $ ErrorCall $ "builtins.functionArgs: expected function, got " <> show _v  toFileNix@@ -1123,18 +1139,18 @@     name' <- fromStringNoContext =<< fromValue name     s'    <- fromValue s     mres  <--      (toFile_ `on` toString)-        name'+      toFile_+        (coerce $ toString name')         (stringIgnoreContext s')      let-      t  = toText $ unStorePath mres-      sc = StringContext t DirectPath+      storepath  = coerce (fromString @Text) mres+      sc = StringContext storepath DirectPath -    toValue $ makeNixStringWithSingletonContext t sc+    toValue $ mkNixStringWithSingletonContext storepath sc  toPathNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)-toPathNix = toValue @Path <=< fromValue @Path+toPathNix = inHask @Path id  pathExistsNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m) pathExistsNix nvpath =@@ -1143,7 +1159,7 @@     toValue =<<       case path of         NVPath p  -> doesPathExist p-        NVStr  ns -> doesPathExist $ toString $ stringIgnoreContext ns+        NVStr  ns -> doesPathExist $ coerce $ toString $ stringIgnoreContext ns         _v -> throwError $ ErrorCall $ "builtins.pathExists: expected path, got " <> show _v  isAttrsNix@@ -1258,8 +1274,8 @@   -> m (NValue t f m) scopedImportNix asetArg pathArg =   do-    s        <- fromValue @(AttrSet (NValue t f m)) asetArg-    (Path p) <- fromValue pathArg+    (coerce -> scope) <- fromValue @(AttrSet (NValue t f m)) asetArg+    p <- fromValue pathArg      path  <- pathToDefaultNix @t @f @m p     path' <-@@ -1270,7 +1286,7 @@         )         (\ res ->           do-            (Path p') <- fromValue =<< demand res+            p' <- fromValue @Path =<< demand res              traceM $ "Current file being evaluated is: " <> show p'             pure $ takeDirectory p' </> path@@ -1279,36 +1295,34 @@      clearScopes @(NValue t f m)       $ withNixContext (pure path')-      $ pushScope s+      $ pushScope scope       $ importPath @t @f @m path'  getEnvNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m) getEnvNix v =-  do-    s <- fromStringNoContext =<< fromValue v-    mres <- getEnvVar s--    toValue $ makeNixStringWithoutContext $-      fromMaybe mempty mres+  (toValue . mkNixStringWithoutContext . maybeToMonoid) =<< getEnvVar =<< fromStringNoContext =<< fromValue v  sortNix-  :: MonadNix e t f m+  :: forall e t f m+  . MonadNix e t f m   => NValue t f m   -> NValue t f m   -> m (NValue t f m)-sortNix comp = toValue <=< sortByM (cmp comp) <=< fromValue+sortNix comp =+  inHaskM (sortByM cmp)  where-  cmp f a b =-    do-      isLessThan <- (`callFunc` b) =<< callFunc f a-      bool-        (do-          isGreaterThan <- (`callFunc` a) =<< callFunc f b-          fromValue isGreaterThan <&>-            bool EQ GT-        )-        (pure LT)-        =<< fromValue isLessThan+  cmp :: NValue t f m -> NValue t f m -> m Ordering+  cmp a b =+    bool+      (fmap+         (bool EQ GT)+         (compare b a)+      )+      (pure LT)+      =<< compare a b+   where+    compare :: NValue t f m -> NValue t f m -> m Bool+    compare a2 a1 = fromValue =<< (`callFunc` a1) =<< callFunc comp a2  lessThanNix   :: MonadNix e t f m@@ -1343,10 +1357,11 @@   -> NValue t f m   -> m (NValue t f m) concatWith f =-  toValue . concat <=<-    traverse-      (fromValue @[NValue t f m] <=< f)-      <=< fromValue @[NValue t f m]+  toValue .+    concat <=<+      traverse+        (fromValue @[NValue t f m] <=< f)+        <=< fromValue @[NValue t f m]  -- | Nix function of Haskell: -- > concat :: [[a]] -> [a]@@ -1377,7 +1392,7 @@         (\ nvattrset ->           do             a <- fromValue @(AttrSet (NValue t f m)) =<< demand nvattrset-            name <- fromStringNoContext =<< fromValue =<< demand =<< attrsetGet "name" a+            (coerce -> name) <- fromStringNoContext =<< fromValue =<< demand =<< attrsetGet "name" a             val  <- attrsetGet "value" a              pure (name, val)@@ -1413,17 +1428,17 @@         mkHash s = hash $ encodeUtf8 s  -placeHolderNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)+placeHolderNix :: forall t f m e . MonadNix e t f m => NValue t f m -> m (NValue t f m) placeHolderNix p =   do     t <- fromStringNoContext =<< fromValue p     h <--      runPrim $-        (hashStringNix `on` makeNixStringWithoutContext)+      coerce @(Prim m NixString) @(m NixString) $+        (hashStringNix `on` mkNixStringWithoutContext)           "sha256"           ("nix-output:" <> t)     toValue-      $ makeNixStringWithoutContext+      $ mkNixStringWithoutContext       $ Text.cons '/'       $ Base32.encode       -- Please, stop Text -> Bytestring here after migration to Text@@ -1440,7 +1455,7 @@       bytes :: NixString -> ByteString       bytes = encodeUtf8 . body -      body h = stringIgnoreContext h+      body = stringIgnoreContext  readFileNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m) readFileNix = toValue <=< Nix.Render.readFile <=< absolutePathFromValue <=< demand@@ -1459,7 +1474,7 @@     case (aset, filePath) of       (NVList x, NVStr ns) ->         do-          mres <- findPath @t @f @m x $ toString $ stringIgnoreContext ns+          mres <- findPath @t @f @m x $ coerce $ toString $ stringIgnoreContext ns            pure $ nvPath mres @@ -1475,6 +1490,7 @@     items          <- listDirectory path      let+      detectFileTypes :: Path -> m (VarName, FileType)       detectFileTypes item =         do           s <- getSymbolicLinkStatus $ path </> item@@ -1486,7 +1502,7 @@                 | isSymbolicLink s -> FileTypeSymlink                 | otherwise        -> FileTypeUnknown -          pure (toText item, t)+          pure (coerce @Text @VarName $ toText item, t) -- function indeed binds filepaths as keys (VarNames) in Nix attrset.      itemsWithTypes <-       traverse@@ -1563,7 +1579,7 @@           NVBuiltin _ _ -> "lambda"           _             -> error "Pattern synonyms obscure complete patterns" -    toValue $ makeNixStringWithoutContext detectType+    toValue $ mkNixStringWithoutContext detectType  tryEvalNix   :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)@@ -1623,7 +1639,7 @@   :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m) fetchurlNix =   (\case-    NVSet s _ -> go (M.lookup "sha256" s) =<< demand =<< attrsetGet "url" s+    NVSet _ s -> go (M.lookup "sha256" s) =<< demand =<< attrsetGet "url" s     v@NVStr{} -> go Nothing v     v -> throwError $ ErrorCall $ "builtins.fetchurl: Expected URI or set, got " <> show v   ) <=< demand@@ -1697,7 +1713,7 @@     case v' of       (NVStr ns) -> do         let context = getNixLikeContext $ toNixLikeContext $ getContext ns-        valued :: AttrSet (NValue t f m) <- sequenceA $ toValue <$> context+        valued :: AttrSet (NValue t f m) <- traverseToValue context         pure $ nvSet mempty valued       x -> throwError $ ErrorCall $ "Invalid type for builtins.getContext: " <> show x @@ -1713,7 +1729,7 @@     y <- demand ty      case (x, y) of-      (NVStr ns, NVSet attrs _) ->+      (NVStr ns, NVSet _ attrs) ->         do           newContextValues <- traverse getPathNOuts attrs @@ -1727,7 +1743,7 @@       x <- demand tx        case x of-        NVSet attrs _ ->+        NVSet _ attrs->           do             -- TODO: Fail for unexpected keys. @@ -1759,7 +1775,7 @@         _x -> throwError $ ErrorCall $ "Invalid types for context value in builtins.appendContext: " <> show _x    addContext ns newContextValues =-    makeNixString+    mkNixString       (stringIgnoreContext ns)       (fromNixLikeContext $         NixLikeContext $@@ -1772,18 +1788,18 @@             )       ) +nixVersionNix :: MonadNix e t f m => m (NValue t f m)+nixVersionNix = toValue $ mkNixStringWithoutContext "2.3" +langVersionNix :: MonadNix e t f m => m (NValue t f m)+langVersionNix = toValue (5 :: Int)+ -- ** @builtinsList@  builtinsList :: forall e t f m . MonadNix e t f m => m [Builtin (NValue t f m)]-builtinsList = sequence-  [ do-      version <- toValue (makeNixStringWithoutContext "2.3")-      pure $ Builtin Normal ("nixVersion", version)-  , do-      version <- toValue (5 :: Int)-      pure $ Builtin Normal ("langVersion", version)-+builtinsList = sequenceA+  [ add0 Normal   "nixVersion"       nixVersionNix+  , add0 Normal   "langVersion"      langVersionNix   , add  TopLevel "abort"            throwNix -- for now   , add2 Normal   "add"              addNix   , add2 Normal   "addErrorContext"  addErrorContextNix@@ -1888,42 +1904,46 @@   , add  Normal   "valueSize"        getRecursiveSizeNix   ]  where++  arity0 :: a -> Prim m a+  arity0 = Prim . pure+   arity1 :: (a -> b) -> (a -> Prim m b)-  arity1 f = Prim . pure . f+  arity1 g = arity0 . g    arity2 :: (a -> b -> c) -> (a -> b -> Prim m c)-  arity2 f = ((Prim . pure) .) . f+  arity2 f = arity1 . f -  mkBuiltin :: BuiltinType -> Text -> m (NValue t f m) -> m (Builtin (NValue t f m))+  mkBuiltin :: BuiltinType -> VarName -> m (NValue t f m) -> m (Builtin (NValue t f m))   mkBuiltin t n v = wrap t n <$> mkThunk n v    where-    wrap :: BuiltinType -> Text -> v -> Builtin v+    wrap :: BuiltinType -> VarName -> v -> Builtin v     wrap t n f = Builtin t (n, f) -    mkThunk :: Text -> m (NValue t f m) -> m (NValue t f m)+    mkThunk :: VarName -> m (NValue t f m) -> m (NValue t f m)     mkThunk n = defer . withFrame Info (ErrorCall $ "While calling builtin " <> toString n <> "\n")    hAdd-    :: ( Text+    :: ( VarName       -> fun       -> m (NValue t f m)       )     -> BuiltinType-    -> Text+    -> VarName     -> fun     -> m (Builtin (NValue t f m))   hAdd f t n v = mkBuiltin t n $ f n v    add0     :: BuiltinType-    -> Text+    -> VarName     -> m (NValue t f m)     -> m (Builtin (NValue t f m))   add0 = hAdd (\ _ x -> x)    add     :: BuiltinType-    -> Text+    -> VarName     -> ( NValue t f m       -> m (NValue t f m)       )@@ -1932,7 +1952,7 @@    add2     :: BuiltinType-    -> Text+    -> VarName     -> ( NValue t f m       -> NValue t f m       -> m (NValue t f m)@@ -1942,7 +1962,7 @@    add3     :: BuiltinType-    -> Text+    -> VarName     -> ( NValue t f m       -> NValue t f m       -> NValue t f m@@ -1954,10 +1974,10 @@   add'     :: ToBuiltin t f m a     => BuiltinType-    -> Text+    -> VarName     -> a     -> m (Builtin (NValue t f m))-  add' = hAdd toBuiltin+  add' = hAdd (toBuiltin . coerce)   -- * Exported@@ -1966,7 +1986,7 @@ withNixContext   :: forall e t f m r    . (MonadNix e t f m, Has e Options)-  => Maybe FilePath+  => Maybe Path   -> m r   -> m r withNixContext mpath action =@@ -1977,7 +1997,7 @@       i = nvList $ nvStrWithoutContext . toText <$> include opts      pushScope-      (one ("__includes", i))+      (coerce $ M.fromList $ one ("__includes", i))       (pushScopes         base $         maybe@@ -1986,29 +2006,35 @@             do               traceM $ "Setting __cur_file = " <> show path               let ref = nvPath path-              pushScope (one ("__cur_file", ref)) act+              pushScope (coerce $ M.fromList $ one ("__cur_file", ref)) act           )           mpath           action       )  builtins-  :: ( MonadNix e t f m+  :: forall e t f m+  . ( MonadNix e t f m      , Scoped (NValue t f m) m      )   => m (Scopes m (NValue t f m)) builtins =   do     ref <- defer $ nvSet mempty <$> buildMap-    lst <- ([("builtins", ref)] <>) <$> topLevelBuiltins-    pushScope (M.fromList lst) currentScopes+    lst <- (one ("builtins", ref) <>) <$> topLevelBuiltins+    pushScope (coerce (M.fromList lst)) currentScopes  where-  buildMap         =  fmap (M.fromList . fmap mapping) builtinsList+  buildMap :: m (HashMap VarName (NValue t f m))+  buildMap         =  M.fromList . (mapping <$>) <$> builtinsList++  topLevelBuiltins :: m [(VarName, NValue t f m)]   topLevelBuiltins = mapping <<$>> fullBuiltinsList +  fullBuiltinsList :: m [Builtin (NValue t f m)]   fullBuiltinsList = nameBuiltins <<$>> builtinsList    where+    nameBuiltins :: Builtin v -> Builtin v     nameBuiltins b@(Builtin TopLevel _) = b     nameBuiltins (Builtin Normal nB) =-      Builtin TopLevel $ first ("__" <>) nB+      Builtin TopLevel $ first (coerce @Text . ("__" <>) . coerce @VarName) nB 
src/Nix/Cache.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE CPP #-}+{-# language CPP #-}  -- | Reading and writing Nix cache files module Nix.Cache where -import qualified Data.ByteString.Lazy          as BS+import qualified Data.ByteString.Lazy          as BSL import           Nix.Expr.Types.Annotated  #if defined (__linux__)@@ -17,7 +17,7 @@ #endif import qualified Codec.Serialise               as S -readCache :: FilePath -> IO NExprLoc+readCache :: Path -> IO NExprLoc readCache path = do #if USE_COMPACT   eres <- C.unsafeReadCompact path@@ -26,17 +26,17 @@     (\ expr -> pure $ C.getCompact expr)     eres #else-  eres <- S.deserialiseOrFail <$> BS.readFile path+  eres <- S.deserialiseOrFail <$> BSL.readFile (coerce path)   either     (\ err  -> fail $ "Error reading cache file: " <> show err)     pure     eres #endif -writeCache :: FilePath -> NExprLoc -> IO ()+writeCache :: Path -> NExprLoc -> IO () writeCache path expr = #ifdef USE_COMPACT   C.writeCompact path =<< C.compact expr #else-  BS.writeFile path (S.serialise expr)+  BSL.writeFile (coerce path) (S.serialise expr) #endif
src/Nix/Cited.hs view
@@ -1,7 +1,7 @@-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE TemplateHaskell #-}+{-# language DeriveAnyClass #-}+{-# language TemplateHaskell #-} -{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# options_ghc -Wno-missing-signatures #-}  module Nix.Cited where 
src/Nix/Cited/Basic.hs view
@@ -1,12 +1,9 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE PatternSynonyms    #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language UndecidableInstances #-}+{-# language PatternSynonyms    #-}  module Nix.Cited.Basic where -import           Prelude                 hiding ( force ) import           Control.Comonad                ( Comonad ) import           Control.Comonad.Env            ( ComonadEnv ) import           Control.Monad.Catch     hiding ( catchJust )@@ -14,11 +11,10 @@ import           Nix.Eval                      as Eval                                                 ( EvalFrame(EvaluatingExpr,ForcingExpr) ) import           Nix.Exec-import           Nix.Expr+import           Nix.Expr.Types.Annotated import           Nix.Frames import           Nix.Options import           Nix.Thunk-import           Nix.Utils import           Nix.Value  @@ -94,11 +90,11 @@             -- Gather the current evaluation context at the time of thunk             -- creation, and record it along with the thunk.             let-              go (fromException -> Just (EvaluatingExpr scope (AnnE s e))) =-                let e' = AnnFP s (Nothing <$ e) in-                [Provenance scope e']+              go :: SomeException -> [Provenance m (NValue u f m)]+              go (fromException -> Just (EvaluatingExpr scope (Ann s e))) =+                one $ Provenance scope $ AnnF s (Nothing <$ e)               go _ = mempty-              ps = concatMap (go . frame) frames+              ps = foldMap (go . frame) frames              cite ps t         )@@ -182,6 +178,6 @@ displayProvenance =   list     id-    (\ (Provenance scope e@(AnnFP s _) : _) ->+    (\ (Provenance scope e@(AnnF s _) : _) ->       withFrame Info $ ForcingExpr scope $ wrapExprLoc s e     )
src/Nix/Context.hs view
@@ -7,8 +7,8 @@ import           Nix.Expr.Types.Annotated       ( SrcSpan                                                 , nullSpan                                                 )-import           Nix.Utils                      ( Has(..) ) +--  2021-07-18: NOTE: It should be Options -> Scopes -> Frames -> Source(span) data Context m t = Context     { scopes  :: Scopes m t     , source  :: SrcSpan
src/Nix/Convert.hs view
@@ -1,11 +1,10 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE IncoherentInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language IncoherentInstances #-}+{-# language TypeFamilies #-}+{-# language UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# options_ghc -fno-warn-name-shadowing #-}  -- | Although there are a lot of instances in this file, really it's just a --   combinatorial explosion of the following combinations:@@ -16,7 +15,6 @@  module Nix.Convert where -import           Prelude                 hiding ( force ) import           Control.Monad.Free import qualified Data.HashMap.Lazy             as M import           Nix.Atoms@@ -28,7 +26,6 @@ import           Nix.Value import           Nix.Value.Monad import           Nix.Thunk                      ( MonadThunk(force) )-import           Nix.Utils  newtype Deeper a = Deeper a   deriving (Typeable, Functor, Foldable, Traversable)@@ -50,13 +47,39 @@ -}  +type Convertible e t f m+  = (Framed e m, MonadDataErrorContext t f m, MonadThunk t m (NValue t f m))++-- | Transform Nix -> Hask. Run function. Convert Hask -> Nix.+inHask :: forall a1 a2 v b m . (Monad m, FromValue a1 m v, ToValue a2 m b) => (a1 -> a2) -> v -> m b+inHask f = toValue . f <=< fromValue++inHaskM :: forall a1 a2 v b m . (Monad m, FromValue a1 m v, ToValue a2 m b) => (a1 -> m a2) -> v -> m b+inHaskM f = toValue <=< f <=< fromValue++-- | Maybe transform Nix -> Hask. Run function. Convert Hask -> Nix.+inHaskMay :: forall a1 a2 v b m . (Monad m, FromValue a1 m v, ToValue a2 m b) => (Maybe a1 -> a2) -> v -> m b+inHaskMay f = toValue . f <=< fromValueMay++ -- * FromValue  class FromValue a m v where   fromValue    :: v -> m a   fromValueMay :: v -> m (Maybe a) +traverseFromM+  :: ( Applicative m+     , Traversable t+     , FromValue b m a+     )+  => t a+  -> m (Maybe (t b))+traverseFromM = traverseM fromValueMay +traverseToValue :: ((Traversable t, Applicative f, ToValue a f b) => t a -> f (t b))+traverseToValue = traverse toValue+ -- Please, hide these helper function from export, to be sure they get optimized away. fromMayToValue   :: forall t f m a e@@ -67,12 +90,10 @@   -> NValue' t f m (NValue t f m)   -> m a fromMayToValue t v =-  do-    v' <- fromValueMay v-    maybe-      (throwError $ Expectation @t @f @m t (Free v))-      pure-      v'+  maybe+    (throwError $ Expectation @t @f @m t (Free v))+    pure+    =<< fromValueMay v  fromMayToDeeperValue   :: forall t f m a e m1@@ -83,15 +104,10 @@   -> Deeper (NValue' t f m (NValue t f m))   -> m (m1 a) fromMayToDeeperValue t v =-  do-    v' <- fromValueMay v-    maybe-      (throwError $ Expectation @t @f @m t $ Free $ (coerce :: CoerceDeeperToNValue' t f m) v)-      pure-      v'--type Convertible e t f m-  = (Framed e m, MonadDataErrorContext t f m, MonadThunk t m (NValue t f m))+  maybe+    (throwError $ Expectation @t @f @m t $ Free $ (coerce :: CoerceDeeperToNValue' t f m) v)+    pure+    =<< fromValueMay v  instance ( Convertible e t f m          , MonadValue (NValue t f m) m@@ -135,7 +151,7 @@   fromValueMay =     pure .       \case-        NVConstant' NNull -> pass+        NVConstant' NNull -> stub         _                 -> mempty    fromValue = fromMayToValue TNull@@ -195,17 +211,18 @@     \case       NVStr' ns -> pure $ pure ns       NVPath' p ->-        fmap-          (pure . (\s -> makeNixStringWithSingletonContext s (StringContext s DirectPath)) . toText . unStorePath)-          (addPath p)-      NVSet' s _ ->+        (\path -> pure $ mkNixStringWithSingletonContext path (StringContext path DirectPath)) . fromString . coerce <$>+          addPath p+      NVSet' _ s ->         maybe           stub           fromValueMay           (M.lookup "outPath" s)       _ -> stub -  fromValue = fromMayToValue $ TString NoContext+  --  2021-07-18: NOTE: There may be cases where conversion wrongly marks the content to have a context.+  --  See: https://github.com/haskell-nix/hnix/pull/958#issuecomment-881949183 thread.+  fromValue = fromMayToValue $ TString HasContext  instance Convertible e t f m   => FromValue ByteString m (NValue' t f m (NValue t f m)) where@@ -213,15 +230,22 @@   fromValueMay =     pure .       \case-        NVStr' ns -> encodeUtf8 <$> getStringNoContext  ns+        NVStr' ns -> encodeUtf8 <$> getStringNoContext ns         _         -> mempty -  fromValue = fromMayToValue $ TString NoContext+  fromValue = fromMayToValue $ TString mempty +instance Convertible e t f m+  => FromValue Text m (NValue' t f m (NValue t f m)) where -newtype Path = Path { getPath :: FilePath }-    deriving Show+  fromValueMay =+    pure .+      \case+        NVStr' ns -> getStringNoContext ns+        _         -> mempty +  fromValue = fromMayToValue $ TString mempty+ instance ( Convertible e t f m          , MonadValue (NValue t f m) m          )@@ -229,14 +253,14 @@    fromValueMay =     \case-      NVPath' p  -> pure $ pure $ Path p-      NVStr'  ns -> pure $ Path . toString <$> getStringNoContext  ns-      NVSet' s _ ->+      NVPath' p  -> pure $ pure $ coerce p+      NVStr'  ns -> pure $ coerce . toString <$> getStringNoContext  ns+      NVSet' _ s ->         maybe-          (pure Nothing)+          stub           (fromValueMay @Path)           (M.lookup "outPath" s)-      _ -> pure Nothing+      _ -> stub    fromValue = fromMayToValue TPath @@ -257,7 +281,7 @@   => FromValue [a] m (Deeper (NValue' t f m (NValue t f m))) where   fromValueMay =     \case-      Deeper (NVList' l) -> sequence <$> traverse fromValueMay l+      Deeper (NVList' l) -> traverseFromM l       _                  -> stub  @@ -269,7 +293,7 @@   fromValueMay =     pure .       \case-        NVSet' s _ -> pure s+        NVSet' _ s -> pure s         _          -> mempty    fromValue = fromMayToValue TSet@@ -281,19 +305,19 @@    fromValueMay =     \case-      Deeper (NVSet' s _) -> sequence <$> traverse fromValueMay s+      Deeper (NVSet' _ s) -> traverseFromM s       _                   -> stub    fromValue = fromMayToDeeperValue TSet  instance Convertible e t f m-  => FromValue (AttrSet (NValue t f m), AttrSet SourcePos) m+  => FromValue (AttrSet (NValue t f m), PositionSet) m               (NValue' t f m (NValue t f m)) where    fromValueMay =     pure .       \case-        NVSet' s p -> pure (s, p)+        NVSet' p s -> pure (s, p)         _          -> mempty    fromValue = fromMayToValue TSet@@ -301,12 +325,12 @@ instance ( Convertible e t f m          , FromValue a m (NValue t f m)          )-  => FromValue (AttrSet a, AttrSet SourcePos) m+  => FromValue (AttrSet a, PositionSet) m               (Deeper (NValue' t f m (NValue t f m))) where    fromValueMay =     \case-      Deeper (NVSet' s p) -> fmap (, p) . sequence <$> traverse fromValueMay s+      Deeper (NVSet' p s) -> (, p) <<$>> traverseFromM s       _                   -> stub    fromValue = fromMayToDeeperValue TSet@@ -325,13 +349,15 @@ class ToValue a m v where   toValue :: a -> m v -instance (Convertible e t f m, ToValue a m (NValue' t f m (NValue t f m)))+instance (Convertible e t f m+  , ToValue a m (NValue' t f m (NValue t f m))+  )   => ToValue a m (NValue t f m) where   toValue v = Free <$> toValue v  instance ( Convertible e t f m-         , ToValue a m (Deeper (NValue' t f m (NValue t f m)))-         )+  , ToValue a m (Deeper (NValue' t f m (NValue t f m)))+  )   => ToValue a m (Deeper (NValue t f m)) where   toValue v = Free <<$>> toValue v @@ -361,24 +387,27 @@  instance Convertible e t f m   => ToValue ByteString m (NValue' t f m (NValue t f m)) where-  toValue = pure . nvStr' . makeNixStringWithoutContext . decodeUtf8+  toValue = pure . nvStr' . mkNixStringWithoutContext . decodeUtf8  instance Convertible e t f m+  => ToValue Text m (NValue' t f m (NValue t f m)) where+  toValue = pure . nvStr' . mkNixStringWithoutContext++instance Convertible e t f m   => ToValue Path m (NValue' t f m (NValue t f m)) where-  toValue = pure . nvPath' . getPath+  toValue = pure . nvPath' . coerce  instance Convertible e t f m   => ToValue StorePath m (NValue' t f m (NValue t f m)) where-  toValue = toValue . Path . unStorePath+  toValue = toValue @Path . coerce -instance ( Convertible e t f m-         )+instance Convertible e t f m   => ToValue SourcePos m (NValue' t f m (NValue t f m)) where   toValue (SourcePos f l c) = do-    f' <- toValue $ makeNixStringWithoutContext $ toText f+    f' <- toValue $ mkNixStringWithoutContext $ fromString f     l' <- toValue $ unPos l     c' <- toValue $ unPos c-    let pos = M.fromList [("file" :: Text, f'), ("line", l'), ("column", c')]+    let pos = M.fromList [("file" :: VarName, f'), ("line", l'), ("column", c')]     pure $ nvSet' mempty pos  -- | With 'ToValue', we can always act recursively@@ -386,9 +415,11 @@   => ToValue [NValue t f m] m (NValue' t f m (NValue t f m)) where   toValue = pure . nvList' -instance (Convertible e t f m, ToValue a m (NValue t f m))+instance (Convertible e t f m+  , ToValue a m (NValue t f m)+  )   => ToValue [a] m (Deeper (NValue' t f m (NValue t f m))) where-  toValue l = Deeper . nvList' <$> traverse toValue l+  toValue l = Deeper . nvList' <$> traverseToValue l  instance Convertible e t f m   => ToValue (AttrSet (NValue t f m)) m (NValue' t f m (NValue t f m)) where@@ -398,20 +429,20 @@   => ToValue (AttrSet a) m (Deeper (NValue' t f m (NValue t f m))) where   toValue s =     liftA2 (\ v s -> Deeper $ nvSet' s v)-      (traverse toValue s)+      (traverseToValue s)       stub  instance Convertible e t f m-  => ToValue (AttrSet (NValue t f m), AttrSet SourcePos) m+  => ToValue (AttrSet (NValue t f m), PositionSet) m             (NValue' t f m (NValue t f m)) where   toValue (s, p) = pure $ nvSet' p s  instance (Convertible e t f m, ToValue a m (NValue t f m))-  => ToValue (AttrSet a, AttrSet SourcePos) m+  => ToValue (AttrSet a, PositionSet) m             (Deeper (NValue' t f m (NValue t f m))) where   toValue (s, p) =     liftA2 (\ v s -> Deeper $ nvSet' s v)-      (traverse toValue s)+      (traverseToValue s)       (pure p)  instance Convertible e t f m@@ -427,9 +458,9 @@     allOutputs <- g nlcvAllOutputs     outputs <- do       let-        outputs = makeNixStringWithoutContext <$> nlcvOutputs nlcv+        outputs = mkNixStringWithoutContext <$> nlcvOutputs nlcv -      ts :: [NValue t f m] <- traverse toValue outputs+      ts :: [NValue t f m] <- traverseToValue outputs       list         (pure Nothing)         (fmap pure . toValue)
src/Nix/Effects.hs view
@@ -1,24 +1,21 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE PackageImports #-} -- 2021-07-05: Due to hashing Haskell IT system situation, in HNix we currently ended-up with 2 hash package dependencies @{hashing, cryptonite}@+{-# language AllowAmbiguousTypes #-}+{-# language CPP #-}+{-# language DefaultSignatures #-}+{-# language TypeFamilies #-}+{-# language DataKinds #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language UndecidableInstances #-}+{-# language PackageImports #-} -- 2021-07-05: Due to hashing Haskell IT system situation, in HNix we currently ended-up with 2 hash package dependencies @{hashing, cryptonite}@ -{-# OPTIONS_GHC -Wno-orphans #-}+{-# options_ghc -Wno-orphans #-}   module Nix.Effects where -import           Prelude                 hiding ( traceM-                                                , putStr-                                                , putStrLn+import           Prelude                 hiding ( putStrLn                                                 , print                                                 )-import qualified Prelude-import           Nix.Utils+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import qualified Data.HashSet                  as HS import qualified Data.Text                     as Text import           Network.HTTP.Client     hiding ( path, Proxy )@@ -26,15 +23,13 @@ import           Network.HTTP.Types import qualified "cryptonite" Crypto.Hash      as Hash import           Nix.Utils.Fix1-import           Nix.Expr+import           Nix.Expr.Types.Annotated import           Nix.Frames              hiding ( Proxy ) import           Nix.Parser import           Nix.Render import           Nix.Value import qualified Paths_hnix import           System.Exit-import qualified System.Environment            as Env-import           System.FilePath                ( takeFileName ) import qualified System.Info import           System.Process @@ -42,7 +37,7 @@ import qualified System.Nix.StorePath          as Store  -- | A path into the nix store-newtype StorePath = StorePath { unStorePath :: FilePath }+newtype StorePath = StorePath Path   -- All of the following type classes defer to the underlying 'm'.@@ -62,16 +57,15 @@   )   => MonadEffects t f m where -  -- | Determine the absolute path of relative path in the current context-  makeAbsolutePath :: FilePath -> m FilePath-  findEnvPath :: String -> m FilePath+  -- | Determine the absolute path in the current context.+  toAbsolutePath :: Path -> m Path+  findEnvPath :: String -> m Path -  -- | Having an explicit list of sets corresponding to the NIX_PATH-  -- and a file path try to find an existing path-  findPath :: [NValue t f m] -> FilePath -> m FilePath+  -- | Having an explicit list of sets corresponding to the @NIX_PATH@ and a file path try to find an existing path.+  findPath :: [NValue t f m] -> Path -> m Path -  importPath :: FilePath -> m (NValue t f m)-  pathToDefaultNix :: FilePath -> m FilePath+  importPath :: Path -> m (NValue t f m)+  pathToDefaultNix :: Path -> m Path    derivationStrict :: NValue t f m -> m (NValue t f m) @@ -108,7 +102,7 @@ #ifdef MIN_VERSION_ghc_datasize     recursiveSize #else-    \_ -> pure 0+    const $ pure 0 #endif  deriving@@ -140,9 +134,9 @@   exec' = \case     []            -> pure $ Left $ ErrorCall "exec: missing program"     (prog : args) -> do-      (exitCode, out, _) <- liftIO $ readProcessWithExitCode (toString prog) (toString <$> args) ""+      (exitCode, out, _) <- liftIO $ readProcessWithExitCode (toString prog) (toString <$> args) mempty       let-        t    = Text.strip $ toText out+        t    = Text.strip $ fromString out         emsg = "program[" <> prog <> "] args=" <> show args       case exitCode of         ExitSuccess ->@@ -191,7 +185,7 @@         readProcessWithExitCode           "nix-instantiate"           ["--eval", "--expr", toString expr]-          ""+          mempty        pure $         case exitCode of@@ -199,7 +193,7 @@             either               (\ e -> Left $ ErrorCall $ "Error parsing output of nix-instantiate: " <> show e)               pure-              (parseNixTextLoc $ toText out)+              (parseNixTextLoc $ fromString out)           status -> Left $ ErrorCall $ "nix-instantiate failed: " <> show status <> ": " <> err  deriving@@ -235,12 +229,12 @@ -- ** Instances  instance MonadEnv IO where-  getEnvVar            = (<<$>>) toText . Env.lookupEnv . toString+  getEnvVar            = (<<$>>) fromString . lookupEnv . toString -  getCurrentSystemOS   = pure $ toText System.Info.os+  getCurrentSystemOS   = pure $ fromString System.Info.os    -- Invert the conversion done by GHC_CONVERT_CPU in GHC's aclocal.m4-  getCurrentSystemArch = pure $ toText $ case System.Info.arch of+  getCurrentSystemArch = pure $ fromString $ case System.Info.arch of     "i386" -> "i686"     arch   -> arch @@ -260,15 +254,15 @@ class   Monad m   => MonadPaths m where-  getDataDir :: m FilePath-  default getDataDir :: (MonadTrans t, MonadPaths m', m ~ t m') => m FilePath+  getDataDir :: m Path+  default getDataDir :: (MonadTrans t, MonadPaths m', m ~ t m') => m Path   getDataDir = lift getDataDir   -- ** Instances  instance MonadPaths IO where-  getDataDir = Paths_hnix.getDataDir+  getDataDir = coerce Paths_hnix.getDataDir  deriving   instance@@ -328,7 +322,7 @@ -- * @class MonadPutStr m@  class-  Monad m+  (Monad m, MonadIO m)   => MonadPutStr m where    --TODO: Should this be used *only* when the Nix to be evaluated invokes a@@ -336,7 +330,7 @@   --  2021-04-01: Due to trace operation here, leaving it as String.   putStr :: String -> m ()   default putStr :: (MonadTrans t, MonadPutStr m', m ~ t m') => String -> m ()-  putStr = lift . putStr+  putStr = lift . Prelude.putStr   -- ** Instances@@ -358,7 +352,7 @@ -- ** Functions  putStrLn :: MonadPutStr m => String -> m ()-putStrLn = putStr . (<> "\n")+putStrLn = Nix.Effects.putStr . (<> "\n")  print :: (MonadPutStr m, Show a) => a -> m () print = putStrLn . show@@ -370,7 +364,7 @@ type RecursiveFlag = Bool type RepairFlag = Bool type StorePathName = Text-type FilePathFilter m = FilePath -> m Bool+type PathFilter m = Path -> m Bool type StorePathSet = HS.HashSet StorePath  -- ** @class MonadStore m@@@ -382,8 +376,8 @@   -- | Copy the contents of a local path to the store.  The resulting store   -- path is returned.  Note: This does not support yet support the expected   -- `filter` function that allows excluding some files.-  addToStore :: StorePathName -> FilePath -> RecursiveFlag -> RepairFlag -> m (Either ErrorCall StorePath)-  default addToStore :: (MonadTrans t, MonadStore m', m ~ t m') => StorePathName -> FilePath -> RecursiveFlag -> RepairFlag -> m (Either ErrorCall StorePath)+  addToStore :: StorePathName -> Path -> RecursiveFlag -> RepairFlag -> m (Either ErrorCall StorePath)+  default addToStore :: (MonadTrans t, MonadStore m', m ~ t m') => StorePathName -> Path -> RecursiveFlag -> RepairFlag -> m (Either ErrorCall StorePath)   addToStore a b c d = lift $ addToStore a b c d    -- | Like addToStore, but the contents written to the output path is a@@ -403,10 +397,10 @@       (\ pathName ->         do           -- TODO: redesign the filter parameter-          res <- Store.Remote.runStore $ Store.Remote.addToStore @Hash.SHA256 pathName path recursive (const False) repair+          res <- Store.Remote.runStore $ Store.Remote.addToStore @Hash.SHA256 pathName (coerce path) recursive (const False) repair           either             Left -- err-            (pure . StorePath . decodeUtf8 . Store.storePathToRawFilePath) -- store path+            (pure . StorePath . coerce . decodeUtf8 @FilePath @ByteString . Store.storePathToRawFilePath) -- store path             <$> parseStoreResult "addToStore" res       )       (Store.makeStorePathName name)@@ -416,7 +410,7 @@       res <- Store.Remote.runStore $ Store.Remote.addTextToStore name text references repair       either         Left -- err-        (pure . StorePath . decodeUtf8 . Store.storePathToRawFilePath) -- path+        (pure . StorePath . coerce . decodeUtf8 @FilePath @ByteString . Store.storePathToRawFilePath) -- path         <$> parseStoreResult "addTextToStore" res  @@ -438,12 +432,12 @@     pure     =<< addTextToStore' a b c d -addPath :: (Framed e m, MonadStore m) => FilePath -> m StorePath+addPath :: (Framed e m, MonadStore m) => Path -> m StorePath addPath p =   either     throwError     pure-    =<< addToStore (toText $ takeFileName p) p True False+    =<< addToStore (fromString $ coerce takeFileName p) p True False -toFile_ :: (Framed e m, MonadStore m) => FilePath -> String -> m StorePath-toFile_ p contents = addTextToStore (toText p) (toText contents) mempty False+toFile_ :: (Framed e m, MonadStore m) => Path -> Text -> m StorePath+toFile_ p contents = addTextToStore (toText p) contents mempty False
src/Nix/Effects/Basic.hs view
@@ -1,27 +1,24 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ViewPatterns #-}+{-# language CPP #-}  module Nix.Effects.Basic where -import           Prelude                 hiding ( traceM-                                                , head+import           Prelude                 hiding ( head                                                 ) import           Relude.Unsafe                  ( head )-import           Nix.Utils+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import           Control.Monad                  ( foldM ) import qualified Data.HashMap.Lazy             as M import           Data.List.Split                ( splitOn ) import qualified Data.Text                     as Text import           Prettyprinter                  ( fillSep )-import           System.FilePath import           Nix.Convert import           Nix.Effects import           Nix.Exec                       ( MonadNix                                                 , evalExprLoc                                                 , nixInstantiateExpr                                                 )-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Frames import           Nix.Parser import           Nix.Render@@ -34,137 +31,134 @@ import           GHC.DataSize #endif -defaultMakeAbsolutePath :: MonadNix e t f m => FilePath -> m FilePath-defaultMakeAbsolutePath origPath = do-  origPathExpanded <- expandHomePath origPath-  absPath          <--    bool-      (do-        cwd <- do-          mres <- lookupVar "__cur_file"-          maybe-            getCurrentDirectory-            (-              (\case-                NVPath s -> pure $ takeDirectory s-                val -> throwError $ ErrorCall $ "when resolving relative path, __cur_file is in scope, but is not a path; it is: " <> show val-              ) <=< demand++++defaultToAbsolutePath :: forall e t f m . MonadNix e t f m => Path -> m Path+defaultToAbsolutePath origPath =+  do+    origPathExpanded <- expandHomePath origPath+    fmap+      removeDotDotIndirections+      . canonicalizePath+        =<< bool+            (fmap+              (<///> origPathExpanded)+              $ maybe+                  getCurrentDirectory+                  ( (\case+                      NVPath s -> pure $ takeDirectory s+                      val -> throwError $ ErrorCall $ "when resolving relative path, __cur_file is in scope, but is not a path; it is: " <> show val+                    ) <=< demand+                  )+                  =<< lookupVar "__cur_file"             )-            mres-        pure $ cwd <///> origPathExpanded-      )-      (pure origPathExpanded)-      (isAbsolute origPathExpanded)-  removeDotDotIndirections <$> canonicalizePath absPath+            (pure origPathExpanded)+            (isAbsolute origPathExpanded) -expandHomePath :: MonadFile m => FilePath -> m FilePath-expandHomePath ('~' : xs) = (<> xs) <$> getHomeDirectory+expandHomePath :: MonadFile m => Path -> m Path+expandHomePath (coerce -> ('~' : xs)) = (<> coerce xs) <$> getHomeDirectory expandHomePath p          = pure p  -- | Incorrectly normalize paths by rewriting patterns like @a/b/..@ to @a@. --   This is incorrect on POSIX systems, because if @b@ is a symlink, its --   parent may be a different directory from @a@. See the discussion at --   https://hackage.haskell.org/package/directory-1.3.1.5/docs/System-Directory.html#v:canonicalizePath-removeDotDotIndirections :: FilePath -> FilePath-removeDotDotIndirections = intercalate "/" . go mempty . splitOn "/"+removeDotDotIndirections :: Path -> Path+removeDotDotIndirections = coerce . intercalate "/" . go mempty . splitOn "/" . coerce  where   go s       []            = reverse s   go (_ : s) (".." : rest) = go s rest   go s       (this : rest) = go (this : s) rest  infixr 9 <///>-(<///>) :: FilePath -> FilePath -> FilePath-x <///> y | isAbsolute y || "." `isPrefixOf` y = x </> y-          | otherwise                          = joinByLargestOverlap x y+(<///>) :: Path -> Path -> Path+x <///> y+  | isAbsolute y || "." `isPrefixOf` coerce y = x </> y+  | otherwise                          = joinByLargestOverlap x y  where+  joinByLargestOverlap :: Path -> Path -> Path   joinByLargestOverlap (splitDirectories -> xs) (splitDirectories -> ys) =     joinPath $ head       [ xs <> drop (length tx) ys | tx <- tails xs, tx `elem` inits ys ] -defaultFindEnvPath :: MonadNix e t f m => String -> m FilePath-defaultFindEnvPath = findEnvPathM--findEnvPathM :: forall e t f m . MonadNix e t f m => FilePath -> m FilePath-findEnvPathM name = do-  mres <- lookupVar "__nixPath"+defaultFindEnvPath :: MonadNix e t f m => String -> m Path+defaultFindEnvPath = findEnvPathM . coerce +findEnvPathM :: forall e t f m . MonadNix e t f m => Path -> m Path+findEnvPathM name =   maybe     (fail "impossible")-    (-      (\ nv ->-        do-          (l :: [NValue t f m]) <- fromValue nv-          findPathBy nixFilePath l name-      ) <=< demand+    (\ v ->+      do+        l <- fromValue @[NValue t f m] =<< demand v+        findPathBy nixFilePath l name     )-    mres+    =<< lookupVar "__nixPath"   where-  nixFilePath :: MonadEffects t f m => FilePath -> m (Maybe FilePath)-  nixFilePath path = do-    absPath <- makeAbsolutePath @t @f path-    isDir   <- doesDirectoryExist absPath-    absFile <--      bool-        (pure absPath)-        (makeAbsolutePath @t @f $ absPath </> "default.nix")-        isDir-    exists <- doesFileExist absFile-    pure $-      bool-        mempty-        (pure absFile)-        exists+  nixFilePath :: MonadEffects t f m => Path -> m (Maybe Path)+  nixFilePath path =+    do+      absPath <- toAbsolutePath @t @f path+      isDir   <- doesDirectoryExist absPath+      absFile <-+        bool+          (pure absPath)+          (toAbsolutePath @t @f $ absPath </> "default.nix")+          isDir +      (pure absFile `whenTrue`) <$> doesFileExist absFile+ findPathBy   :: forall e t f m    . MonadNix e t f m-  => (FilePath -> m (Maybe FilePath))+  => (Path -> m (Maybe Path))   -> [NValue t f m]-  -> FilePath-  -> m FilePath-findPathBy finder ls name = do-  mpath <- foldM go mempty ls+  -> Path+  -> m Path+findPathBy finder ls name =   maybe-    (throwError $ ErrorCall $ "file '" <> name <> "' was not found in the Nix search path (add it's using $NIX_PATH or -I)")+    (throwError $ ErrorCall $ "file ''" <> coerce name <> "'' was not found in the Nix search path (add it's using $NIX_PATH or -I)")     pure-    mpath+    =<< foldM fun mempty ls  where-  go :: Maybe FilePath -> NValue t f m -> m (Maybe FilePath)-  go mp =+  fun+    :: MonadNix e t f m+    => Maybe Path+    -> NValue t f m+    -> m (Maybe Path)+  fun =     maybe       (\ nv ->         do-          (s :: HashMap Text (NValue t f m)) <- fromValue =<< demand nv+          (s :: HashMap VarName (NValue t f m)) <- fromValue =<< demand nv           p <- resolvePath s-          nvpath <- demand p-          (Path path) <- fromValue nvpath+          path <- fromValue =<< demand p            maybe             (tryPath path mempty)             (\ nv' ->               do-                mns <- fromValueMay =<< demand nv'+                mns <- fromValueMay @NixString =<< demand nv'                 tryPath path $-                  case mns of-                    Just (nsPfx :: NixString) ->+                  whenJust+                    (\ nsPfx ->                       let pfx = stringIgnoreContext nsPfx in-                      bool-                        mempty-                        (pure (toString pfx))-                        (not $ Text.null pfx)-                    _ -> mempty+                      pure $ coerce $ toString pfx `whenFalse` Text.null pfx+                    )+                    mns             )             (M.lookup "prefix" s)       )       (const . pure . pure)-      mp -  tryPath :: FilePath -> Maybe FilePath -> m (Maybe FilePath)+  tryPath :: Path -> Maybe Path -> m (Maybe Path)   tryPath p (Just n) | n' : ns <- splitDirectories name, n == n' =     finder $ p <///> joinPath ns   tryPath p _ = finder $ p <///> name +  resolvePath :: HashMap VarName (NValue t f m) -> m (NValue t f m)   resolvePath s =     maybe       (maybe@@ -176,22 +170,29 @@       (M.lookup "path" s)  fetchTarball-  :: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)+  :: forall e t f m+   . MonadNix e t f m+  => NValue t f m+  -> m (NValue t f m) fetchTarball =   \case-    NVSet s _ ->+    NVSet _ s ->       maybe         (throwError $ ErrorCall "builtins.fetchTarball: Missing url attribute")-        (go (M.lookup "sha256" s) <=< demand)+        (fetchFromString (M.lookup "sha256" s) <=< demand)         (M.lookup "url" s)-    v@NVStr{} -> go Nothing v+    v@NVStr{} -> fetchFromString Nothing v     v -> throwError $ ErrorCall $ "builtins.fetchTarball: Expected URI or set, got " <> show v   <=< demand  where-  go :: Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)-  go msha = \case-    NVStr ns -> fetch (stringIgnoreContext ns) msha-    v -> throwError $ ErrorCall $ "builtins.fetchTarball: Expected URI or string, got " <> show v+  fetchFromString+    :: Maybe (NValue t f m)+    -> NValue t f m+    -> m (NValue t f m)+  fetchFromString msha =+    \case+      NVStr ns -> fetch (stringIgnoreContext ns) msha+      v -> throwError $ ErrorCall $ "builtins.fetchTarball: Expected URI or string, got " <> show v  {- jww (2018-04-11): This should be written using pipes in another module     fetch :: Text -> Maybe (NThunk m) -> m (NValue t f m)@@ -206,68 +207,73 @@ -}    fetch :: Text -> Maybe (NValue t f m) -> m (NValue t f m)-  fetch uri Nothing =-    nixInstantiateExpr $ "builtins.fetchTarball \"" <> uri <> "\""-  fetch url (Just t) =-      (\nv -> do-        nsSha <- fromValue nv+  fetch uri =+    maybe+      (nixInstantiateExpr $+        "builtins.fetchTarball \"" <> uri <> "\""+      )+      (\ v ->+        do+          nsSha <- fromValue =<< demand v -        let sha = stringIgnoreContext nsSha+          let sha = stringIgnoreContext nsSha -        nixInstantiateExpr-          $ "builtins.fetchTarball { " <> "url    = \"" <> url <> "\"; " <> "sha256 = \"" <> sha <> "\"; }"-      ) =<< demand t+          nixInstantiateExpr $+            "builtins.fetchTarball { " <> "url    = \"" <> uri <> "\"; " <> "sha256 = \"" <> sha <> "\"; }"+      ) -defaultFindPath :: MonadNix e t f m => [NValue t f m] -> FilePath -> m FilePath+defaultFindPath :: MonadNix e t f m => [NValue t f m] -> Path -> m Path defaultFindPath = findPathM  findPathM   :: forall e t f m    . MonadNix e t f m   => [NValue t f m]-  -> FilePath-  -> m FilePath+  -> Path+  -> m Path findPathM = findPathBy existingPath  where-  existingPath :: MonadEffects t f m => FilePath -> m (Maybe FilePath)+  existingPath :: MonadEffects t f m => Path -> m (Maybe Path)   existingPath path =     do-      apath  <- makeAbsolutePath @t @f path+      apath  <- toAbsolutePath @t @f path       doesExist <- doesPathExist apath       pure $ pure apath `whenTrue` doesExist  defaultImportPath-  :: (MonadNix e t f m, MonadState (HashMap FilePath NExprLoc, b) m)-  => FilePath+  :: (MonadNix e t f m, MonadState (HashMap Path NExprLoc, b) m)+  => Path   -> m (NValue t f m)-defaultImportPath path = do-  traceM $ "Importing file " <> path-  withFrame Info (ErrorCall $ "While importing file " <> show path) $ do-    imports <- gets fst-    evalExprLoc =<<-      maybe-        (do-          eres <- parseNixFileLoc path-          either-            (\ err -> throwError $ ErrorCall . show $ fillSep ["Parse during import failed:", err])-            (\ expr ->-              do-                modify (first (M.insert path expr))-                pure expr+defaultImportPath path =+  do+    traceM $ "Importing file " <> coerce path+    withFrame+      Info+      (ErrorCall $ "While importing file " <> show path)+      $ evalExprLoc =<<+          (maybe+            (either+              (\ err -> throwError $ ErrorCall . show $ fillSep ["Parse during import failed:", err])+              (\ expr ->+                do+                  modify $ first $ M.insert path expr+                  pure expr+              )+              =<< parseNixFileLoc path             )-            eres-        )-        pure  -- return expr-        (M.lookup path imports)+            pure  -- return expr+            . M.lookup path+          ) =<< gets fst -defaultPathToDefaultNix :: MonadNix e t f m => FilePath -> m FilePath+defaultPathToDefaultNix :: MonadNix e t f m => Path -> m Path defaultPathToDefaultNix = pathToDefaultNixFile  -- Given a path, determine the nix file to load-pathToDefaultNixFile :: MonadFile m => FilePath -> m FilePath-pathToDefaultNixFile p = do-  isDir <- doesDirectoryExist p-  pure $ p </> "default.nix" `whenTrue` isDir+pathToDefaultNixFile :: MonadFile m => Path -> m Path+pathToDefaultNixFile p =+  do+    isDir <- doesDirectoryExist p+    pure $ p </> "default.nix" `whenTrue` isDir  defaultTraceEffect :: MonadPutStr m => String -> m () defaultTraceEffect = Nix.Effects.putStrLn
src/Nix/Effects/Derivation.hs view
@@ -1,12 +1,12 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE NamedFieldPuns #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE PackageImports #-} -- 2021-07-05: Due to hashing Haskell IT system situation, in HNix we currently ended-up with 2 hash package dependencies @{hashing, cryptonite}@+{-# language DataKinds #-}+{-# language NamedFieldPuns #-}+{-# language RecordWildCards #-}+{-# language PackageImports #-} -- 2021-07-05: Due to hashing Haskell IT system situation, in HNix we currently ended-up with 2 hash package dependencies @{hashing, cryptonite}@  module Nix.Effects.Derivation ( defaultDerivationStrict ) where -import           Nix.Utils+import           Prelude                 hiding ( readFile )+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import           Data.Char                      ( isAscii                                                 , isAlphaNum                                                 )@@ -24,6 +24,7 @@ import qualified "cryptonite" Crypto.Hash      as Hash -- 2021-07-05: Attrocity of Haskell hashing situation, in HNix we ended-up with 2 hash package dependencies @{hashing, cryptonite}@  import           Nix.Atoms+import           Nix.Expr.Types          hiding ( Recursive ) import           Nix.Convert import           Nix.Effects import           Nix.Exec                       ( MonadNix@@ -40,9 +41,9 @@ import qualified System.Nix.ReadonlyStore      as Store import qualified System.Nix.Hash               as Store import qualified System.Nix.StorePath          as Store-import Prelude hiding (readFile)  +--  2021-07-17: NOTE: Derivation consists of @"keys"@ @"vals"@ (of text), so underlining type boundary currently stops here. data Derivation = Derivation   { name :: Text   , outputs :: Map Text Text@@ -75,11 +76,11 @@   let (inputSrcs, inputDrvs) = inputs   references <- Set.fromList <$> traverse parsePath (Set.toList $ inputSrcs <> Set.fromList (Map.keys inputDrvs))   path <- addTextToStore (Text.append name ".drv") (unparseDrv drv) (S.fromList $ Set.toList references) False-  parsePath $ toText $ unStorePath path+  parsePath $ fromString $ coerce path  -- | Traverse the graph of inputDrvs to replace fixed output derivations with their fixed output hash. -- this avoids propagating changes to their .drv when the output hash stays the same.-hashDerivationModulo :: (MonadNix e t f m, MonadState (b, AttrSet Text) m) => Derivation -> m (Hash.Digest Hash.SHA256)+hashDerivationModulo :: (MonadNix e t f m, MonadState (b, KeyMap Text) m) => Derivation -> m (Hash.Digest Hash.SHA256) hashDerivationModulo   Derivation     { mFixed = Just (Store.SomeDigest (digest :: Hash.Digest hashType))@@ -91,7 +92,7 @@       Hash.hash @ByteString @Hash.SHA256 $         encodeUtf8 $           "fixed:out"-          <> (if hashMode == Recursive then ":r" else "")+          <> (if hashMode == Recursive then ":r" else mempty)           <> ":" <> (Store.algoName @hashType)           <> ":" <> Store.encodeDigestWith Store.Base16 digest           <> ":" <> path@@ -110,7 +111,7 @@           (\(path, outs) ->             maybe               (do-                drv' <- readDerivation $ toString path+                drv' <- readDerivation $ coerce $ toString path                 hash <- Store.encodeDigestWith Store.Base16 <$> hashDerivationModulo drv'                 pure (hash, outs)               )@@ -144,7 +145,7 @@       ]   where     produceOutputInfo (outputName, outputPath) =-      let prefix = if hashMode == Recursive then "r:" else "" in+      let prefix = if hashMode == Recursive then "r:" else mempty in       parens $ (s <$>) $ ([outputName, outputPath] <>) $         maybe           [mempty, mempty]@@ -168,13 +169,13 @@     escape '\t' = "\\t"     escape c = one c -readDerivation :: (Framed e m, MonadFile m) => FilePath -> m Derivation+readDerivation :: (Framed e m, MonadFile m) => Path -> m Derivation readDerivation path = do-  content <- decodeUtf8 <$> readFile path+  content <- readFile path   either     (\ err -> throwError $ ErrorCall $ "Failed to parse " <> show path <> ":\n" <> show err)     pure-    (parse derivationParser path content)+    (parse derivationParser (coerce path) content)  derivationParser :: Parsec () Text Derivation derivationParser = do@@ -199,13 +200,13 @@    let outputs = Map.fromList $ (\(a, b, _, _) -> (a, b)) <$> fullOutputs   let (mFixed, hashMode) = parseFixed fullOutputs-  let name = "" -- FIXME (extract from file path ?)-  let useJson = ["__json"] == Map.keys env+  let name = mempty -- FIXME (extract from file path ?)+  let useJson = one "__json" == Map.keys env    pure $ Derivation {inputs = (inputSrcs, inputDrvs), ..}  where   s :: Parsec () Text Text-  s = fmap toText $ string "\"" *> manyTill (escaped <|> regular) (string "\"")+  s = fmap fromString $ string "\"" *> manyTill (escaped <|> regular) (string "\"")   escaped = char '\\' *>     (   '\n' <$ string "n"     <|> '\r' <$ string "r"@@ -218,12 +219,13 @@     string o *> sepBy p (string ",") <* string c    parens :: Parsec () Text a -> Parsec () Text [a]-  parens p = wrap "(" ")" p-  serializeList p = wrap "[" "]" p+  parens = wrap "(" ")"+  serializeList :: Parsec () Text a -> Parsec () Text [a]+  serializeList = wrap "[" "]"    parseFixed :: [(Text, Text, Text, Text)] -> (Maybe Store.SomeNamedDigest, HashMode)   parseFixed fullOutputs = case fullOutputs of-    [("out", _path, rht, hash)] | rht /= "" && hash /= "" ->+    [("out", _path, rht, hash)] | rht /= mempty && hash /= mempty ->       let         (hashType, hashMode) = case Text.splitOn ":" rht of           ["r", ht] -> (ht, Recursive)@@ -238,9 +240,9 @@     _ -> (Nothing, Flat)  -defaultDerivationStrict :: forall e t f m b. (MonadNix e t f m, MonadState (b, AttrSet Text) m) => NValue t f m -> m (NValue t f m)+defaultDerivationStrict :: forall e t f m b. (MonadNix e t f m, MonadState (b, KeyMap Text) m) => NValue t f m -> m (NValue t f m) defaultDerivationStrict val = do-    s <- fromValue @(AttrSet (NValue t f m)) val+    s <- M.mapKeys coerce <$> fromValue @(AttrSet (NValue t f m)) val     (drv, ctx) <- runWithStringContextT' $ buildDerivationWithContext s     drvName <- makeStorePathName $ name drv     let@@ -266,47 +268,50 @@               ifNotJsonModEnv                 (\ baseEnv ->                   foldl'-                    (\m k -> Map.insert k "" m)+                    (\m k -> Map.insert k mempty m)                     baseEnv                     (Map.keys $ outputs drv)                 )           }-        outputs' <- sequence $ Map.mapWithKey (\o _ -> makeOutputPath o hash drvName) $ outputs drv+        outputs' <- sequenceA $ Map.mapWithKey (\o _ -> makeOutputPath o hash drvName) $ outputs drv         pure $ drv           { inputs           , outputs = outputs'-          , env = ifNotJsonModEnv $ (outputs' <>)+          , env = ifNotJsonModEnv (outputs' <>)           } -    drvPath <- pathToText <$> writeDerivation drv'+    (coerce @Text @VarName -> drvPath) <- pathToText <$> writeDerivation drv'      -- Memoize here, as it may be our last chance in case of readonly stores.     drvHash <- Store.encodeDigestWith Store.Base16 <$> hashDerivationModulo drv'-    modify $ second $ MS.insert drvPath drvHash+    modify $ second $ MS.insert (coerce drvPath) drvHash      let       outputsWithContext =         Map.mapWithKey-          (\out path -> makeNixStringWithSingletonContext path $ StringContext drvPath $ DerivationOutput out)+          (\out (coerce -> path) -> mkNixStringWithSingletonContext path $ StringContext drvPath $ DerivationOutput out)           (outputs drv')-      drvPathWithContext = makeNixStringWithSingletonContext drvPath $ StringContext drvPath AllOutputs+      drvPathWithContext = mkNixStringWithSingletonContext drvPath $ StringContext drvPath AllOutputs       attrSet = nvStr <$> M.fromList (("drvPath", drvPathWithContext) : Map.toList outputsWithContext)     -- TODO: Add location information for all the entries.     --              here --v-    pure $ nvSet mempty attrSet+    pure $ nvSet mempty (M.mapKeys coerce attrSet)    where      pathToText = decodeUtf8 . Store.storePathToRawFilePath      makeOutputPath o h n = do-      name <- makeStorePathName $ Store.unStorePathName n <> if o == "out" then "" else "-" <> o+      name <- makeStorePathName $ Store.unStorePathName n <> if o == "out" then mempty else "-" <> o       pure $ pathToText $ Store.makeStorePath "/nix/store" ("output:" <> encodeUtf8 o) h name -    toStorePaths ctx = foldl (flip addToInputs) (mempty, mempty) ctx+    toStorePaths :: HashSet StringContext -> (Set Text, Map Text [Text])+    toStorePaths = foldl (flip addToInputs) mempty++    addToInputs :: Bifunctor p => StringContext -> p (Set Text) (Map Text [Text])  -> p (Set Text) (Map Text [Text])     addToInputs (StringContext path kind) = case kind of-      DirectPath -> first (Set.insert path)-      DerivationOutput o -> second (Map.insertWith (<>) path [o])+      DirectPath -> first (Set.insert (coerce path))+      DerivationOutput o -> second (Map.insertWith (<>) (coerce path) $ one o)       AllOutputs ->         -- TODO: recursive lookup. See prim_derivationStrict         -- XXX: When is this really used ?@@ -316,7 +321,7 @@ -- | Build a derivation in a context collecting string contexts. -- This is complex from a typing standpoint, but it allows to perform the -- full computation without worrying too much about all the string's contexts.-buildDerivationWithContext :: forall e t f m. (MonadNix e t f m) => AttrSet (NValue t f m) -> WithStringContextT m Derivation+buildDerivationWithContext :: forall e t f m. (MonadNix e t f m) => KeyMap (NValue t f m) -> WithStringContextT m Derivation buildDerivationWithContext drvAttrs = do     -- Parse name first, so we can add an informative frame     drvName     <- getAttr   "name"                      $ assertDrvStoreName <=< extractNixString@@ -330,13 +335,13 @@       platform    <- getAttr   "system"                    $ assertNonNull <=< extractNoCtx       mHash       <- getAttrOr "outputHash"        mempty  $ (pure . pure) <=< extractNoCtx       hashMode    <- getAttrOr "outputHashMode"    Flat    $ parseHashMode <=< extractNoCtx-      outputs     <- getAttrOr "outputs"           ["out"] $ traverse (extractNoCtx <=< fromValue')+      outputs     <- getAttrOr "outputs"       (one "out") $ traverse (extractNoCtx <=< fromValue')        mFixedOutput <-         maybe           (pure Nothing)           (\ hash -> do-            when (outputs /= ["out"]) $ lift $ throwError $ ErrorCall "Multiple outputs are not supported for fixed-output derivations"+            when (outputs /= one "out") $ lift $ throwError $ ErrorCall "Multiple outputs are not supported for fixed-output derivations"             hashType <- getAttr "outputHashAlgo" extractNoCtx             digest <- lift $ either (throwError . ErrorCall) pure $ Store.mkNamedDigest hashType hash             pure $ pure digest)@@ -362,7 +367,7 @@        env <- if useJson         then do-          jsonString :: NixString <- lift $ nvalueToJSONNixString $ nvSet mempty $+          jsonString :: NixString <- lift $ nvalueToJSONNixString $ nvSet mempty $ M.mapKeys coerce $             deleteKeys [ "args", "__ignoreNulls", "__structuredAttrs" ] attrs           rawString :: Text <- extractNixString jsonString           pure $ one ("__json", rawString)@@ -374,7 +379,7 @@         , name = drvName         , outputs = Map.fromList $ (, mempty) <$> outputs         , mFixed = mFixedOutput-        , inputs = (mempty, mempty) -- stub for now+        , inputs = mempty -- stub for now         }   where @@ -386,7 +391,7 @@     withFrame' :: (Framed e m, Exception s) => NixLevel -> s -> WithStringContextT m a -> WithStringContextT m a     withFrame' level f = join . lift . withFrame level f . pure -    -- shortcuts to get the (forced) value of an AttrSet field+    -- shortcuts to get the (forced) value of an KeyMap field      getAttrOr' :: forall v a. (MonadNix e t f m, FromValue v m (NValue' t f m (NValue t f m)))       => Text -> m a -> (v -> WithStringContextT m a) -> WithStringContextT m a@@ -395,7 +400,7 @@       Just v  -> withFrame' Info (ErrorCall $ "While evaluating attribute '" <> show n <> "'") $                    f =<< fromValue' v -    getAttrOr n d f = getAttrOr' n (pure d) f+    getAttrOr n = getAttrOr' n . pure      getAttr n = getAttrOr' n (throwError $ ErrorCall $ "Required attribute '" <> show n <> "' not found.") @@ -431,6 +436,6 @@      -- Other helpers -    deleteKeys :: [Text] -> AttrSet a -> AttrSet a+    deleteKeys :: [Text] -> KeyMap a -> KeyMap a     deleteKeys keys attrSet = foldl' (flip M.delete) attrSet keys 
src/Nix/Eval.hs view
@@ -1,38 +1,39 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language RankNTypes #-}    module Nix.Eval where +import           Relude.Extra                   ( set ) import           Control.Monad                  ( foldM ) import           Control.Monad.Fix              ( MonadFix )+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import           Data.Semialign.Indexed         ( ialignWith ) import qualified Data.HashMap.Lazy             as M import           Data.List                      ( partition ) import           Data.These                     ( These(..) ) import           Nix.Atoms import           Nix.Convert-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Expr.Strings               ( runAntiquoted ) import           Nix.Frames import           Nix.String import           Nix.Scope-import           Nix.Utils import           Nix.Value.Monad  class (Show v, Monad m) => MonadEval v m where-  freeVariable    :: Text -> m v-  synHole         :: Text -> m v-  attrMissing     :: NonEmpty Text -> Maybe v -> m v-  evaledSym       :: Text -> v -> m v+  freeVariable    :: VarName -> m v+  synHole         :: VarName -> m v+  attrMissing     :: NonEmpty VarName -> Maybe v -> m v+  evaledSym       :: VarName -> v -> m v   evalCurPos      :: m v   evalConstant    :: NAtom -> m v   evalString      :: NString (m v) -> m v-  evalLiteralPath :: FilePath -> m v-  evalEnvPath     :: FilePath -> m v+  evalLiteralPath :: Path -> m v+  evalEnvPath     :: Path -> m v   evalUnary       :: NUnaryOp -> v -> m v   evalBinary      :: NBinaryOp -> v -> m v -> m v   -- ^ The second argument is an action because operators such as boolean &&@@ -60,9 +61,9 @@   evalListElem   :: [m v] -> Int -> m v -> m v   evalList       :: [v] -> m v   evalSetElem    :: AttrSet (m v) -> Text -> m v -> m v-  evalSet        :: AttrSet v -> AttrSet SourcePos -> m v+  evalSet        :: AttrSet v -> PositionSet -> m v   evalRecSetElem :: AttrSet (m v) -> Text -> m v -> m v-  evalRecSet     :: AttrSet v -> AttrSet SourcePos -> m v+  evalRecSet     :: AttrSet v -> PositionSet -> m v   evalLetElem    :: Text -> m v -> m v   evalLet        :: m v -> m v -}@@ -76,8 +77,8 @@   , ToValue Bool m v   , ToValue [v] m v   , FromValue NixString m v-  , ToValue (AttrSet v, AttrSet SourcePos) m v-  , FromValue (AttrSet v, AttrSet SourcePos) m v+  , ToValue (AttrSet v, PositionSet) m v+  , FromValue (AttrSet v, PositionSet) m v   )  data EvalFrame m v@@ -129,12 +130,12 @@     lav <- larg     evalBinary op lav rarg -eval (NSelect aset attr alt ) =+eval (NSelect alt aset attr) =   do     let useAltOrReportMissing (s, ks) = fromMaybe (attrMissing ks $ pure s) alt      eAttr <- evalSelect aset attr-    either useAltOrReportMissing id eAttr+    either useAltOrReportMissing id (coerce eAttr)  eval (NHasAttr aset attr) =   do@@ -144,23 +145,17 @@ eval (NList l           ) =   do     scope <- currentScopes-    lst <- traverse (defer @v @m . withScopes @v scope) l-    toValue lst--eval (NSet NNonRecursive binds) =-  do-    attrSet <- evalBinds False $ desugarBinds (eval . NSet NNonRecursive) binds-    toValue attrSet+    toValue =<< traverse (defer @v @m . withScopes @v scope) l -eval (NSet NRecursive binds) =+eval (NSet r binds) =   do-    attrSet <- evalBinds True $ desugarBinds (eval . NSet NNonRecursive) binds+    attrSet <- evalBinds (r == Recursive) $ desugarBinds (eval . NSet mempty) binds     toValue attrSet  eval (NLet binds body    ) =   do     (attrSet, _) <- evalBinds True binds-    pushScope attrSet body+    pushScope (coerce attrSet) body  eval (NIf cond t f       ) =   do@@ -179,78 +174,97 @@   -- needs to be used when evaluating the body and default arguments, hence we   -- defer here so the present scope is restored when the parameters and body   -- are forced during application.-  scope <- currentScopes :: m (Scopes m v)+  curScope <- currentScopes   let-    withScope = withScopes scope-    withScopeInform = withScope . inform+    withCurScope = withScopes curScope -  evalAbs-    params-    (\arg k ->-      withScope $+    fun :: m v -> (AttrSet (m v) -> m v -> m r) -> m r+    fun arg k =+      withCurScope $         do-          args <- buildArgument params arg+          (coerce -> newScopeToAdd) <- buildArgument params arg           pushScope-            args $+            newScopeToAdd $             k-              (withScopeInform <$> args)+              (coerce $ withCurScope . inform <$> newScopeToAdd)               body-    ) +  evalAbs+    params+    fun+ eval (NSynHole name) = synHole name  -- | If you know that the 'scope' action will result in an 'AttrSet v', then --   this implementation may be used as an implementation for 'evalWith'. evalWithAttrSet :: forall v m . MonadNixEval v m => m v -> m v -> m v evalWithAttrSet aset body = do-  scope <- currentScopes :: m (Scopes m v)+  scopes <- currentScopes :: m (Scopes m v)   -- The scope is deliberately wrapped in a thunk here, since it is demanded   -- each time a name is looked up within the weak scope, and we want to be   -- sure the action it evaluates is to force a thunk, so its value is only   -- computed once.-  deferredAset <- defer $ withScopes scope aset-  let attrSet = fst <$> (fromValue @(AttrSet v, AttrSet SourcePos) =<< demand deferredAset)+  deferredAset <- defer $ withScopes scopes aset+  let weakscope = coerce . fst <$> (fromValue @(AttrSet v, PositionSet) =<< demand deferredAset) -  pushWeakScope attrSet body+  pushWeakScope weakscope body  attrSetAlter   :: forall v m    . MonadNixEval v m-  => [Text]+  => [VarName]   -> SourcePos   -> AttrSet (m v)-  -> AttrSet SourcePos+  -> PositionSet   -> m v-  -> m (AttrSet (m v), AttrSet SourcePos)-attrSetAlter [] _ _ _ _ = evalError @v $ ErrorCall "invalid selector with no components"-attrSetAlter (k : ks) pos m p val =-  bool-    go-    (maybe-      (recurse mempty mempty)-      (\x ->-        do-          (st, sp) <- fromValue @(AttrSet v, AttrSet SourcePos) =<< x-          recurse (demand <$> st) sp-      )-      (M.lookup k m)-    )-    (not $ null ks)+  -> m (AttrSet (m v), PositionSet)+attrSetAlter ks' pos m' p' val =+  swap <$> go p' m' ks'  where-  go = pure (M.insert k val m, M.insert k pos p)--  recurse st sp =-    (\(st', _) ->-      (M.insert-        k-        (toValue @(AttrSet v, AttrSet SourcePos) =<< (, mempty) <$> sequence st')-        m-      , M.insert k pos p+  -- This `go` does traverse in disquise. Notice how it traverses `ks`.+  go+    :: PositionSet+    -> AttrSet (m v)+    -> [VarName]+    -> m (PositionSet, AttrSet (m v))+  go _ _ [] = evalError @v $ ErrorCall "invalid selector with no components"+  go p m (k : ks) =+    bool+      (pure $ insertVal val)+      (maybe+        (recurse mempty mempty)+        (\x ->+          do+            --  2021-10-12: NOTE: swapping sourcewide into (PositionSet, AttrSet) would optimize code and remove this `swap`+            (swap -> (sp, st)) <- fromValue @(AttrSet v, PositionSet) =<< x+            recurse sp $ demand <$> st+        )+        ((`M.lookup` m) k)       )-    ) <$> attrSetAlter ks pos st sp val+      (not $ null ks)+   where+    insertVal :: m v -> (PositionSet, AttrSet (m v))+    insertVal v =+      ( insertPos+      , insertV v+      )+     where+      insertV v' = M.insert k v' m+      insertPos = M.insert k pos p +    recurse+      :: PositionSet+      -> AttrSet (m v)+      -> m ( PositionSet+          , AttrSet (m v)+          )+    recurse p'' m'' =+      fmap+        (insertVal . (=<<) (toValue @(AttrSet v, PositionSet)) . fmap (,mempty) . sequenceA . snd)+        (go p'' m'' ks)+ desugarBinds :: forall r . ([Binding r] -> r) -> [Binding r] -> [Binding r]-desugarBinds embed binds = evalState (traverse (go <=< collect) binds) mempty+desugarBinds embed binds = evalState (traverse (findBinding <=< collect) binds) mempty  where   collect     :: Binding r@@ -261,76 +275,79 @@     do       m <- get       put $-        M.insert-          x-          (maybe-            (p, [bindValAt p])-            (\ (q, v) -> (q, bindValAt q : v))-            (M.lookup x m)+        join+          (M.insert+            x+            . maybe+              (p, one $ bindValAt p)+              (\ (sp, bnd) -> (sp, one (bindValAt sp) <> bnd))+              . M.lookup x           )           m       pure $ Left x    where-    bindValAt pos = NamedVar (y :| ys) val pos+    bindValAt = NamedVar (y :| ys) val   collect x = pure $ pure x -  go+  findBinding     :: Either VarName (Binding r)     -> State (HashMap VarName (SourcePos, [Binding r])) (Binding r)-  go =+  findBinding =     either-      (\ x -> do-        maybeValue <- gets $ M.lookup x+      (\ x ->         maybe           (error $ "No binding " <> show x)-          (\ (p, v) -> pure $ NamedVar (StaticKey x :| mempty) (embed v) p)-          maybeValue+          (\ (p, v) -> pure $ NamedVar (one $ StaticKey x) (embed v) p)+          =<< gets (M.lookup x)       )       pure  evalBinds   :: forall v m    . MonadNixEval v m+--  2021-07-19: NOTE: Recutsivity data type   => Bool   -> [Binding (m v)]-  -> m (AttrSet v, AttrSet SourcePos)-evalBinds recursive binds =+--  2021-07-19: NOTE: AttrSet is a Scope+  -> m (AttrSet v, PositionSet)+evalBinds isRecursive binds =   do     scope <- currentScopes :: m (Scopes m v) -    buildResult scope . concat =<< traverse (applyBindToAdt scope) (moveOverridesLast binds)+    buildResult scope . fold =<< (`traverse` moveOverridesLast binds) (applyBindToAdt scope)   where   buildResult     :: Scopes m v-    -> [([Text], SourcePos, m v)]-    -> m (AttrSet v, AttrSet SourcePos)-  buildResult scope bindings =+    -> [([VarName], SourcePos, m v)]+    -> m (AttrSet v, PositionSet)+  buildResult scopes bindings =     do-      (s, p) <- foldM insert (mempty, mempty) bindings+      (coerce -> scope, p) <- foldM insert mempty bindings       res <-         bool-          (traverse mkThunk s)-          (loebM $ encapsulate <$> s)-          recursive+          (traverse mkThunk)+          (loebM . fmap encapsulate)+          isRecursive+          scope -      pure (res, p)+      pure (coerce res, p)     where     insert (m, p) (path, pos, value) = attrSetAlter path pos m p value -    mkThunk = defer . withScopes scope+    mkThunk = defer . withScopes scopes      encapsulate f attrs = mkThunk $ pushScope attrs f -  applyBindToAdt :: Scopes m v -> Binding (m v) -> m [([Text], SourcePos, m v)]+  applyBindToAdt :: Scopes m v -> Binding (m v) -> m [([VarName], SourcePos, m v)]   applyBindToAdt _ (NamedVar (StaticKey "__overrides" :| []) finalValue pos) =     do       (o', p') <- fromValue =<< finalValue       -- jww (2018-05-09): What to do with the key position here?       pure $         (\ (k, v) ->-          ( [k]+          ( one k           , fromMaybe pos $ M.lookup k p'           , demand v           )@@ -341,19 +358,19 @@       -- When there are no path segments, e.g. `${null} = 5;`, we don't       -- bind anything       ([], _, _) -> mempty-      result     -> [result]+      result     -> one result     ) <$> processAttrSetKeys pathExpr     where-    processAttrSetKeys :: NAttrPath (m v) -> m ([Text], SourcePos, m v)+    processAttrSetKeys :: NAttrPath (m v) -> m ([VarName], SourcePos, m v)     processAttrSetKeys (h :| t) =       maybe         -- Empty attrset - return a stub.-        (pure ( mempty, nullPos, toValue @(AttrSet v, AttrSet SourcePos) (mempty, mempty)) )+        (pure (mempty, nullPos, toValue @(AttrSet v, PositionSet) mempty) )         (\ k ->           list             -- No more keys in the attrset - return the result-            (pure ( [k], pos, finalValue ) )+            (pure ( one k, pos, finalValue ) )             -- There are unprocessed keys in attrset - recurse appending the results             (\ (x : xs) ->               do@@ -364,37 +381,28 @@         )         =<< evalSetterKeyName h -  applyBindToAdt scope (Inherit ms names pos) =-    catMaybes <$>-      traverse-        processScope-        names+  applyBindToAdt scopes (Inherit ms names pos) =+    pure $ processScope <$> names    where     processScope-      :: NKeyName (m v)-      -> m (Maybe ([Text], SourcePos, m v))-    processScope nkeyname =-      (\ mkey ->-        do-          key <- mkey-          pure-            ([key]-            , pos-            , maybe-                (attrMissing (key :| mempty) Nothing)-                demand-                =<< maybe-                    (withScopes scope $ lookupVar key)-                    (\ s ->-                      do-                        (attrset, _) <- fromValue @(AttrSet v, AttrSet SourcePos) =<< s+      :: VarName+      -> ([VarName], SourcePos, m v)+    processScope var =+      ( one var+      , pos+      , maybe+          (attrMissing (one var) Nothing)+          demand+          =<< maybe+              (withScopes scopes $ lookupVar var)+              (\ s ->+                do+                  (coerce -> scope, _) <- fromValue @(AttrSet v, PositionSet) =<< s -                        clearScopes @v $ pushScope attrset $ lookupVar key-                    )-                    ms-            )-      ) <$>-        evalSetterKeyName nkeyname+                  clearScopes $ pushScope @v scope $ lookupVar var+              )+              ms+      )    moveOverridesLast = uncurry (<>) . partition     (\case@@ -407,30 +415,33 @@    . MonadNixEval v m   => m v   -> NAttrPath (m v)-  -> m (Either (v, NonEmpty Text) (m v))+  -> m (Either (v, NonEmpty VarName) (m v)) evalSelect aset attr =   do     s    <- aset     path <- traverse evalGetterKeyName attr -    extract s path+    extract path s   where-  extract x path@(k :| ks) =-    do-      x' <- fromValueMay x--      case x' of-        Nothing -> pure $ Left (x, path)-        Just (s :: AttrSet v, p :: AttrSet SourcePos)-          | Just t <- M.lookup k s ->-            do-              list-                (pure . pure)-                (\ (y : ys) -> ((`extract` (y :| ys)) =<<))-                ks-                $ demand t-          | otherwise -> Left . (, path) <$> toValue (s, p)+  extract :: NonEmpty VarName -> v -> m (Either (v, NonEmpty VarName) (m v))+  extract path@(k :| ks) x =+    maybe+      left+      (maybe+        left+        (list+          (pure . pure)+          (\ (y : ys) -> (extract (y :| ys) =<<))+          ks+          . demand+        )+        . M.lookup k . fst+      )+      =<< fromValueMay @(AttrSet v, PositionSet) x+   where+    left :: m (Either (v, NonEmpty VarName) b)+    left = pure $ Left (x, path)  -- | Evaluate a component of an attribute path in a context where we are -- *retrieving* a value@@ -438,7 +449,7 @@   :: forall v m    . (MonadEval v m, FromValue NixString m v)   => NKeyName (m v)-  -> m Text+  -> m VarName evalGetterKeyName =   maybe     (evalError @v $ ErrorCall "value is null while a string was expected")@@ -450,33 +461,29 @@ evalSetterKeyName   :: (MonadEval v m, FromValue NixString m v)   => NKeyName (m v)-  -> m (Maybe Text)+  -> m (Maybe VarName) evalSetterKeyName =   \case     StaticKey k -> pure $ pure k     DynamicKey k ->-      maybe-        mempty-        (pure . stringIgnoreContext)-        <$> runAntiquoted "\n" assembleString (fromValueMay =<<) k+      (coerce . stringIgnoreContext) <<$>>+        runAntiquoted "\n" assembleString (fromValueMay =<<) k  assembleString   :: forall v m    . (MonadEval v m, FromValue NixString m v)   => NString (m v)   -> m (Maybe NixString)-assembleString =-  fromParts .-    \case-      Indented   _ parts -> parts-      DoubleQuoted parts -> parts+assembleString = fromParts . stringParts  where-  fromParts xs = (mconcat <$>) . sequence <$> traverse go xs+  fromParts :: [Antiquoted Text (m v)] -> m (Maybe NixString)+  fromParts xs = fold <<$>> traverseM fun xs -  go =+  fun :: Antiquoted Text (m v) -> m (Maybe NixString)+  fun =     runAntiquoted       "\n"-      (pure . pure . makeNixStringWithoutContext)+      (pure . pure . mkNixStringWithoutContext)       (fromValueMay =<<)  buildArgument@@ -484,43 +491,42 @@ buildArgument params arg =   do     scope <- currentScopes :: m (Scopes m v)-    let argThunk = defer $ withScopes scope arg+    let+      argThunk = defer $ withScopes scope arg     case params of-      Param name -> M.singleton name <$> argThunk-      ParamSet s isVariadic m ->+      Param name -> one . (name,) <$> argThunk+      ParamSet mname variadic pset ->         do-          (args, _) <- fromValue @(AttrSet v, AttrSet SourcePos) =<< arg+          (args, _) <- fromValue @(AttrSet v, PositionSet) =<< arg           let             inject =               maybe                 id-                (\ n -> M.insert n $ const argThunk) -- why insert into const?-                m-          loebM-            (inject $-                M.mapMaybe-                  id-                  (ialignWith-                    (assemble scope isVariadic)+                (`M.insert` const argThunk) -- why insert into const? Thunk value getting magic point?+                mname+          loebM $+            inject $+              M.mapMaybe+                id+                $ ialignWith+                    (assemble scope variadic)                     args-                    $ M.fromList s-                  )-            )+                    $ M.fromList pset  where   assemble     :: Scopes m v-    -> Bool-    -> Text+    -> Variadic+    -> VarName     -> These v (Maybe (m v))     -> Maybe (AttrSet v -> m v)-  assemble scope isVariadic k =-    \case-      That Nothing -> pure $ const $ evalError @v $ ErrorCall $ "Missing value for parameter: " <> show k-      That (Just f) -> pure $ \args -> defer $ withScopes scope $ pushScope args f-      This _-        | isVariadic -> Nothing-        | otherwise  -> pure $ const $ evalError @v $ ErrorCall $ "Unexpected parameter: " <> show k-      These x _ -> pure $ const $ pure x+  assemble _ Variadic _ (This _) = Nothing+  assemble scope _ k t =+    pure $+      case t of+        That Nothing -> const $ evalError @v $ ErrorCall $ "Missing value for parameter: ''" <> show k+        That (Just f) -> coerce $ defer . withScopes scope . (`pushScope` f)+        This _ -> const $ evalError @v $ ErrorCall $ "Unexpected parameter: " <> show k+        These x _ -> const $ pure x  -- | Add source positions to @NExprLoc@. --@@ -533,7 +539,7 @@ -- > -> NExprLoc -> m a addSourcePositions   :: (MonadReader e m, Has e SrcSpan) => Transform NExprLocF (m a)-addSourcePositions f (v@(AnnE ann _) :: NExprLoc) =+addSourcePositions f (v@(Ann ann _) :: NExprLoc) =   local (set hasLens ann) $ f v  addStackFrames@@ -571,4 +577,4 @@   :: MonadNixEval v m   => AnnF ann NExprF (m v)   -> m v-evalContent = eval . stripAnn+evalContent = eval . stripAnnF
src/Nix/Exec.hs view
@@ -1,14 +1,13 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE PartialTypeSignatures #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}+{-# language AllowAmbiguousTypes #-}+{-# language CPP #-}+{-# language ConstraintKinds #-}+{-# language PartialTypeSignatures #-}+{-# language RankNTypes #-}+{-# language TypeFamilies #-}+{-# language UndecidableInstances #-} -{-# OPTIONS_GHC -Wno-orphans #-}-{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# options_ghc -Wno-orphans #-}+{-# options_ghc -fno-warn-name-shadowing #-}   module Nix.Exec where@@ -17,7 +16,7 @@                                                 , putStrLn                                                 , print                                                 )-+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import           Control.Monad.Catch     hiding ( catchJust ) import           Control.Monad.Fix import           Data.Fix@@ -29,7 +28,8 @@ import           Nix.Convert import           Nix.Effects import           Nix.Eval                      as Eval-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Frames import           Nix.Options import           Nix.Pretty@@ -38,7 +38,6 @@ import           Nix.String import           Nix.String.Coerce import           Nix.Thunk-import           Nix.Utils import           Nix.Value import           Nix.Value.Equal import           Nix.Value.Monad@@ -72,7 +71,7 @@ nvPathP   :: MonadCited t f m   => Provenance m (NValue t f m)-  -> FilePath+  -> Path   -> NValue t f m nvPathP p x = addProvenance p $ nvPath x @@ -86,7 +85,7 @@ nvSetP   :: MonadCited t f m   => Provenance m (NValue t f m)-  -> AttrSet SourcePos+  -> PositionSet   -> AttrSet (NValue t f m)   -> NValue t f m nvSetP p x s = addProvenance p $ nvSet x s@@ -102,7 +101,7 @@ nvBuiltinP   :: MonadCited t f m   => Provenance m (NValue t f m)-  -> Text+  -> VarName   -> (NValue t f m -> m (NValue t f m))   -> NValue t f m nvBuiltinP p name f = addProvenance p $ nvBuiltin name f@@ -140,21 +139,21 @@ currentPos = asks $ view hasLens  wrapExprLoc :: SrcSpan -> NExprLocF r -> NExprLoc-wrapExprLoc span x = Fix $ Fix (NSym_ span "<?>") <$ x+wrapExprLoc span x = Fix $ NSymAnn span "<?>" <$ x {-# inline wrapExprLoc #-}  --  2021-01-07: NOTE: This instance belongs to be beside MonadEval type class. -- Currently instance is stuck in orphanage between the requirements to be MonadEval, aka Eval stage, and emposed requirement to be MonadNix (Execution stage). MonadNix constraint tries to put the cart before horse and seems superflous, since Eval in Nix also needs and can throw exceptions. It is between `nverr` and `evalError`. instance MonadNix e t f m => MonadEval (NValue t f m) m where   freeVariable var =-    nverr @e @t @f $ ErrorCall $ "Undefined variable '" <> toString var <> "'"+    nverr @e @t @f $ ErrorCall $ toString @Text $ "Undefined variable '" <> coerce var <> "'"    synHole name = do     span  <- currentPos     scope <- currentScopes     evalError @(NValue t f m) $ SynHole $       SynHoleInfo-        { _synHoleInfo_expr  = Fix $ NSynHole_ span name+        { _synHoleInfo_expr  = NSynHoleAnn span name         , _synHoleInfo_scope = scope         } @@ -168,13 +167,13 @@         )         ms        where-        attr = Text.intercalate "." $ NE.toList ks+        attr = Text.intercalate "." $ NE.toList $ coerce ks    evalCurPos = do     scope                  <- currentScopes     span@(SrcSpan delta _) <- currentPos     addProvenance @_ @_ @(NValue t f m)-      (Provenance scope $ NSym_ span "__curPos") <$>+      (Provenance scope $ NSymAnnF span (coerce @Text "__curPos")) <$>         toValue delta    evaledSym name val = do@@ -182,13 +181,13 @@     span  <- currentPos     pure $       addProvenance @_ @_ @(NValue t f m)-        (Provenance scope $ NSym_ span name)+        (Provenance scope $ NSymAnnF span name)         val    evalConstant c = do     scope <- currentScopes     span  <- currentPos-    pure $ nvConstantP (Provenance scope $ NConstant_ span c) c+    pure $ join (nvConstantP . Provenance scope . NConstantAnnF span) c    evalString =     maybe@@ -198,10 +197,11 @@           scope <- currentScopes           span  <- currentPos           pure $-            nvStrP-              (Provenance-                scope-                (NStr_ span $ DoubleQuoted [Plain $ stringIgnoreContext ns])+            join+              (nvStrP+                . Provenance+                  scope+                  . NStrAnnF span . DoubleQuoted . one . Plain . stringIgnoreContext               )               ns       )@@ -210,14 +210,24 @@   evalLiteralPath p = do     scope <- currentScopes     span  <- currentPos-    nvPathP (Provenance scope $ NLiteralPath_ span p) <$>-      makeAbsolutePath @t @f @m p+    let+      evalPath :: Path -> m (NValue t f m)+      evalPath p1 =+        fmap+          (g p1)+          (f p1)+       where+        g :: Path -> Path -> NValue t f m+        g = nvPathP . Provenance scope . NLiteralPathAnnF span+        f :: Path -> m Path+        f = toAbsolutePath @t @f @m+    evalPath p    evalEnvPath p = do     scope <- currentScopes     span  <- currentPos-    nvPathP (Provenance scope $ NEnvPath_ span p) <$>-      findEnvPath @t @f @m p+    nvPathP (Provenance scope $ NEnvPathAnnF span p) <$>+      findEnvPath @t @f @m (coerce p)    evalUnary op arg = do     scope <- currentScopes@@ -232,24 +242,24 @@   evalWith c b = do     scope <- currentScopes     span  <- currentPos-    let f = join $ addProvenance . Provenance scope . NWith_ span Nothing . pure+    let f = join $ addProvenance . Provenance scope . NWithAnnF span Nothing . pure     f <$> evalWithAttrSet c b -  evalIf c t f = do+  evalIf c tVal fVal = do     scope <- currentScopes     span  <- currentPos-    b <- fromValue c+    bl <- fromValue c      let-      fun x y z = addProvenance (Provenance scope $ NIf_ span (pure c) x y) z+      fun x y = addProvenance (Provenance scope $ NIfAnnF span (pure c) x y)       -- Note: join acts as \ f x -> f x x-      false = join (fun Nothing . pure) <$> f-      true = join (flip fun Nothing . pure) <$> t+      falseVal = join (fun Nothing . pure) <$> fVal+      trueVal = join (flip fun Nothing . pure) <$> tVal      bool-      false-      true-      b+      falseVal+      trueVal+      bl    evalAssert c body =     do@@ -259,25 +269,26 @@         (nverr $ Assertion span c)         (do           scope <- currentScopes-          let f = join (addProvenance . Provenance scope . NAssert_ span (pure c) . pure)-          f <$> body+          join (addProvenance . Provenance scope . NAssertAnnF span (pure c) . pure) <$> body         )         b    evalApp f x = do     scope <- currentScopes     span  <- currentPos-    addProvenance (Provenance scope $ NBinary_ span NApp (pure f) Nothing) <$>+    addProvenance (Provenance scope $ NBinaryAnnF span NApp (pure f) Nothing) <$>       (callFunc f =<< defer x)    evalAbs p k = do+    let+      fk = flip k     scope <- currentScopes     span  <- currentPos     pure $       nvClosureP-        (Provenance scope $ NAbs_ span (Nothing <$ p) Nothing)+        (Provenance scope $ NAbsAnnF span (Nothing <$ p) Nothing)         (void p)-        (\arg -> snd <$> k (pure arg) (\_ b -> ((), ) <$> b))+        $ fmap snd . fk (const $ fmap ((), )) . pure    evalError = throwError @@ -299,8 +310,8 @@       NVBuiltin name f    ->         do           span <- currentPos-          withFrame Info ((Calling @m @(NValue t f m)) name span) $ f arg -- Is this cool?-      (NVSet m _) | Just f <- M.lookup "__functor" m ->+          withFrame Info ((Calling @m @(NValue t f m)) (coerce name) span) $ f arg -- Is this cool?+      (NVSet _ m) | Just f <- M.lookup "__functor" m ->         (`callFunc` arg) =<< (`callFunc` fun') =<< demand f       _x -> throwError $ ErrorCall $ "Attempt to call non-function: " <> show _x @@ -311,7 +322,7 @@   -> NUnaryOp   -> NValue t f m   -> m (NValue t f m)-execUnaryOp scope span op arg = do+execUnaryOp scope span op arg =   case arg of     NVConstant c ->       case (op, c) of@@ -323,7 +334,7 @@     _x ->       throwError $ ErrorCall $ "argument to unary operator must evaluate to an atomic type: " <> show _x  where-  unaryOp = pure . nvConstantP (Provenance scope $ NUnary_ span op $ pure arg)+  unaryOp = pure . nvConstantP (Provenance scope $ NUnaryAnnF span op $ pure arg)  execBinaryOp   :: forall e t f m@@ -351,6 +362,7 @@   where +  helperEq :: (Bool -> Bool) -> m (NValue t f m)   helperEq flag =     do       rval <- rarg@@ -375,7 +387,7 @@   toBoolOp r b =     pure $       nvConstantP-        (Provenance scope $ NBinary_ span op (pure lval) r)+        (Provenance scope $ NBinaryAnnF span op (pure lval) r)         (NBool b)  execBinaryOpForced@@ -403,9 +415,9 @@    NUpdate ->     case (lval, rval) of-      (NVSet ls lp, NVSet rs rp) -> pure $ nvSetP prov (rp <> lp) (rs <> ls)-      (NVSet ls lp, NVConstant NNull) -> pure $ nvSetP prov lp ls-      (NVConstant NNull, NVSet rs rp) -> pure $ nvSetP prov rp rs+      (NVSet lp ls, NVSet rp rs) -> pure $ nvSetP prov (rp <> lp) (rs <> ls)+      (NVSet lp ls, NVConstant NNull) -> pure $ nvSetP prov lp ls+      (NVConstant NNull, NVSet rp rs) -> pure $ nvSetP prov rp rs       _ -> unsupportedTypes    NPlus ->@@ -421,10 +433,10 @@           (throwError $ ErrorCall "A string that refers to a store path cannot be appended to a path.") -- data/nix/src/libexpr/eval.cc:1412           (\ rs2 ->             nvPathP prov <$>-              makeAbsolutePath @t @f (ls <> toString rs2)+              toAbsolutePath @t @f (ls <> coerce (toString rs2))           )           (getStringNoContext rs)-      (NVPath ls, NVPath rs) -> nvPathP prov <$> makeAbsolutePath @t @f (ls <> rs)+      (NVPath ls, NVPath rs) -> nvPathP prov <$> toAbsolutePath @t @f (ls <> rs)        (ls@NVSet{}, NVStr rs) ->         (\ls2 -> nvStrP prov (ls2 <> rs)) <$>@@ -443,7 +455,7 @@   where   prov :: Provenance m (NValue t f m)-  prov = Provenance scope $ NBinary_ span op (pure lval) (pure rval)+  prov = Provenance scope $ NBinaryAnnF span op (pure lval) (pure rval)    toBool = pure . nvConstantP prov . NBool   compare :: (forall a. Ord a => a -> a -> Bool) -> m (NValue t f m)@@ -452,8 +464,8 @@     (NVStr l, NVStr r) -> toBool $ l `op` r     _ -> unsupportedTypes -  toInt = pure . nvConstantP prov . NInt-  toFloat = pure . nvConstantP prov . NFloat+  nvInt = pure . nvConstantP prov . NInt+  nvFloat = pure . nvConstantP prov . NFloat    numBinOp :: (forall a. Num a => a -> a -> a) -> m (NValue t f m)   numBinOp op = numBinOp' op op@@ -462,13 +474,12 @@     :: (Integer -> Integer -> Integer)     -> (Float -> Float -> Float)     -> m (NValue t f m)-   numBinOp' intOp floatOp = case (lval, rval) of     (NVConstant l, NVConstant r) -> case (l, r) of-      (NInt   li, NInt   ri) -> toInt $ li `intOp` ri-      (NInt   li, NFloat rf) -> toFloat $ fromInteger li `floatOp` rf-      (NFloat lf, NInt   ri) -> toFloat $ lf `floatOp` fromInteger ri-      (NFloat lf, NFloat rf) -> toFloat $ lf `floatOp` rf+      (NInt   li, NInt   ri) -> nvInt $ li `intOp` ri+      (NInt   li, NFloat rf) -> nvFloat $ fromInteger li `floatOp` rf+      (NFloat lf, NInt   ri) -> nvFloat $ lf `floatOp` fromInteger ri+      (NFloat lf, NFloat rf) -> nvFloat $ lf `floatOp` rf       _ -> unsupportedTypes     _ -> unsupportedTypes @@ -502,7 +513,7 @@   depth <- ask   guard $ depth < 2000   local succ $ do-    v'@(AnnFP span x) <- sequence v+    v'@(AnnF span x) <- sequenceA v     pure $ do       opts :: Options <- asks $ view hasLens       let
src/Nix/Expr/Shorthands.hs view
@@ -1,251 +1,447 @@  -- | A bunch of shorthands for making nix expressions. ----- Functions with an @F@ suffix return a more general type without the outer--- 'Fix' wrapper.+-- 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           Data.Fix import           Nix.Atoms import           Nix.Expr.Types-import           Text.Megaparsec.Pos            ( SourcePos ) --- | Make an integer literal expression.-mkInt :: Integer -> NExpr-mkInt = Fix . mkIntF+-- * Basic expression builders +-- | Put @NAtom@ as expression+mkConst :: NAtom -> NExpr+mkConst = Fix . NConstant -mkIntF :: Integer -> NExprF a-mkIntF = NConstant . NInt+-- | Put null.+mkNull :: NExpr+mkNull = Fix mkNullF --- | Make an floating point literal expression.+-- | Put boolean.+mkBool :: Bool -> NExpr+mkBool = Fix . mkBoolF++-- | Put integer.+mkInt :: Integer -> NExpr+mkInt = Fix . mkIntF++-- | Put floating point number. mkFloat :: Float -> NExpr mkFloat = Fix . mkFloatF -mkFloatF :: Float -> NExprF a-mkFloatF = NConstant . NFloat---- | Make a regular (double-quoted) string.+-- | Put a regular (double-quoted) string. mkStr :: Text -> NExpr-mkStr = Fix . NStr . DoubleQuoted . \case-  "" -> mempty-  x  -> [Plain x]+mkStr = Fix . NStr . DoubleQuoted .+  whenText+    mempty+    (one . Plain) --- | Make an indented string.+-- | Put an indented string. mkIndentedStr :: Int -> Text -> NExpr-mkIndentedStr w = Fix . NStr . Indented w . \case-  "" -> mempty-  x  -> [Plain x]+mkIndentedStr w = Fix . NStr . Indented w .+  whenText+    mempty+    (one . Plain) --- | Make a path. Use 'True' if the path should be read from the--- environment, else 'False'.+-- | Put a path. Use @True@ if the path should be read from the environment, else use @False@. mkPath :: Bool -> FilePath -> NExpr mkPath b = Fix . mkPathF b -mkPathF :: Bool -> FilePath -> NExprF a-mkPathF False = NLiteralPath-mkPathF True  = NEnvPath---- | Make a path expression which pulls from the NIX_PATH env variable.+-- | Put a path expression which pulls from the @NIX_PATH@ @env@ variable. mkEnvPath :: FilePath -> NExpr mkEnvPath = Fix . mkEnvPathF -mkEnvPathF :: FilePath -> NExprF a-mkEnvPathF = mkPathF True---- | Make a path expression which references a relative path.+-- | Put a path which references a relative path. mkRelPath :: FilePath -> NExpr mkRelPath = Fix . mkRelPathF -mkRelPathF :: FilePath -> NExprF a-mkRelPathF = mkPathF False---- | Make a variable (symbol)+-- | Put a variable (symbol). mkSym :: Text -> NExpr mkSym = Fix . mkSymF -mkSymF :: Text -> NExprF a-mkSymF = NSym-+-- | Put syntactic hole. mkSynHole :: Text -> NExpr mkSynHole = Fix . mkSynHoleF -mkSynHoleF :: Text -> NExprF a-mkSynHoleF = NSynHole- mkSelector :: Text -> NAttrPath NExpr-mkSelector = (:| mempty) . StaticKey+mkSelector = one . StaticKey . coerce -mkBool :: Bool -> NExpr-mkBool = Fix . mkBoolF+-- | Put an unary operator.+--  @since 0.15.0+mkOp :: NUnaryOp -> NExpr -> NExpr+mkOp op = Fix . NUnary op -mkBoolF :: Bool -> NExprF a-mkBoolF = NConstant . NBool+-- | Logical negation: @not@.+mkNot :: NExpr -> NExpr+mkNot = mkOp NNot -mkNull :: NExpr-mkNull = Fix mkNullF+-- | Number negation: @-@.+--+-- Negation in the language works with integers and floating point.+--  @since 0.15.0+mkNeg :: NExpr -> NExpr+mkNeg = mkOp NNeg -mkNullF :: NExprF a-mkNullF = NConstant NNull+-- | Put a binary operator.+--  @since 0.15.0+mkOp2 :: NBinaryOp -> NExpr -> NExpr -> NExpr+mkOp2 op a = Fix . NBinary op a -mkOper :: NUnaryOp -> NExpr -> NExpr-mkOper op = Fix . NUnary op+-- | > { x }+--  @since 0.15.0+mkParamSet :: [(Text, Maybe NExpr)] -> Params NExpr+mkParamSet pset = mkGeneralParamSet Nothing pset False -mkOper2 :: NBinaryOp -> NExpr -> NExpr -> NExpr-mkOper2 op a = Fix . NBinary op a+-- | > { x, ... }+--  @since 0.15.0+mkVariadicParamSet :: [(Text, Maybe NExpr)] -> Params NExpr+mkVariadicParamSet pset = mkGeneralParamSet Nothing pset True -mkParamset :: [(Text, Maybe NExpr)] -> Bool -> Params NExpr-mkParamset params variadic = ParamSet params variadic mempty+-- | > s@{ x }+--  @since 0.15.0+mkNamedParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr+mkNamedParamSet name pset = mkGeneralParamSet (pure name) pset False +-- | > s@{ x, ... }+--  @since 0.15.0+mkNamedVariadicParamSet :: Text -> [(Text, Maybe NExpr)] -> Params NExpr+mkNamedVariadicParamSet name params = mkGeneralParamSet (pure name) params 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 mname params variadic = ParamSet (coerce mname) (Variadic `whenTrue` variadic) (coerce params)++-- | > rec { .. } mkRecSet :: [Binding NExpr] -> NExpr-mkRecSet = Fix . NSet NRecursive+mkRecSet = mkSet Recursive +-- | Put a non-recursive set.+--+-- > { .. } mkNonRecSet :: [Binding NExpr] -> NExpr-mkNonRecSet = Fix . NSet NNonRecursive+mkNonRecSet = mkSet mempty -mkLets :: [Binding NExpr] -> NExpr -> NExpr-mkLets bindings = Fix . NLet bindings+-- | General set builder function.+mkSet :: Recursivity -> [Binding NExpr] -> NExpr+mkSet r = Fix . NSet r +-- | Empty set.+--+-- Monoid. Use @//@ operation (shorthand $//) to extend the set.+--  @since 0.15.0+emptySet :: NExpr+emptySet = mkNonRecSet mempty++-- | Put a list. mkList :: [NExpr] -> NExpr mkList = Fix . NList +--  @since 0.15.0+emptyList :: NExpr+emptyList = mkList 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 bindings = Fix . NLet 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 e = Fix . NWith 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 e = Fix . NWith e+mkAssert e = Fix . NAssert e +-- | Put:+--+-- > if expr1+-- >   then expr2+-- >   else expr3 mkIf :: NExpr -> NExpr -> NExpr -> NExpr mkIf e1 e2 = Fix . NIf e1 e2 +-- | Lambda function, analog of Haskell's @\\ x -> x@:+--+-- +-----------------------+-----------++-- | Haskell               | Nix       |+-- +=======================+===========++-- | @ mkFunction x expr @ | @x: expr@ |+-- +-----------------------+-----------+ mkFunction :: Params NExpr -> NExpr -> NExpr mkFunction params = Fix . NAbs params -{--mkDot :: NExpr -> Text -> NExpr-mkDot e key = mkDots e [key]+-- | General dot-reference with optional alternative if the jey does not exist.+--  @since 0.15.0+getRefOrDefault :: Maybe NExpr -> NExpr -> Text -> NExpr+getRefOrDefault alt obj = Fix . NSelect alt obj . mkSelector --- | Create a dotted expression using only text.-mkDots :: NExpr -> [Text] -> NExpr-mkDots e [] = e-mkDots (Fix (NSelect e keys' x)) keys =-  -- Special case: if the expression in the first argument is already-  -- a dotted expression, just extend it.-  Fix (NSelect e (keys' <> fmap (`StaticKey` Nothing) keys) x)-mkDots e keys = Fix $ NSelect e (fmap (`StaticKey` Nothing) keys) Nothing--}+-- ** Base functor builders for basic expressions builders *sic --- | An `inherit` clause without an expression to pull from.-inherit :: [NKeyName e] -> SourcePos -> Binding e-inherit = Inherit Nothing+-- | Unfixed @mkNull@.+mkNullF :: NExprF a+mkNullF = NConstant NNull +-- | Unfixed @mkBool@.+mkBoolF :: Bool -> NExprF a+mkBoolF = NConstant . NBool++-- | Unfixed @mkInt@.+mkIntF :: Integer -> NExprF a+mkIntF = NConstant . NInt++-- | Unfixed @mkFloat@.+mkFloatF :: Float -> NExprF a+mkFloatF = NConstant . NFloat++-- | Unfixed @mkPath@.+mkPathF :: Bool -> FilePath -> NExprF a+mkPathF False = NLiteralPath . coerce+mkPathF True  = NEnvPath . coerce++-- | Unfixed @mkEnvPath@.+mkEnvPathF :: FilePath -> NExprF a+mkEnvPathF = mkPathF True++-- | Unfixed @mkRelPath@.+mkRelPathF :: FilePath -> NExprF a+mkRelPathF = mkPathF False++-- | Unfixed @mkSym@.+mkSymF :: Text -> NExprF a+mkSymF = NSym . coerce++-- | Unfixed @mkSynHole@.+mkSynHoleF :: Text -> NExprF a+mkSynHoleF = NSynHole . coerce+++-- * Other+-- (org this better/make a better name for section(s))+ -- | An `inherit` clause with an expression to pull from.-inheritFrom :: e -> [NKeyName e] -> SourcePos -> Binding e-inheritFrom expr = Inherit (pure expr)+--+-- +------------------------+--------------------+------------++-- | Hask                   | Nix                | pseudocode |+-- +========================+====================+============++-- | @inheritFrom x [a, b]@ | @inherit (x) a b;@ | @a = x.a;@ |+-- |                        |                    | @b = x.b;@ |+-- +------------------------+--------------------+------------++inheritFrom :: e -> [VarName] -> Binding e+inheritFrom expr ks = Inherit (pure expr) ks nullPos --- | Shorthand for producing a binding of a name to an expression: @=-bindTo :: Text -> NExpr -> Binding NExpr-bindTo name x = NamedVar (mkSelector name) x 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 ks = Inherit Nothing ks nullPos --- | Infix version of @bindTo@: @=@+-- | Nix @=@ (bind operator). ($=) :: 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 name x = NamedVar (mkSelector name) x 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`.+-- 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 newBindings (Fix e) = case e of-  NLet bindings e'    -> Fix $ NLet (bindings <> newBindings) e'-  NSet recur bindings -> Fix $ NSet recur (bindings <> newBindings)-  _                   -> error "Can only append bindings to a set or a let"+appendBindings newBindings (Fix e) =+  case e of+    NLet bindings e'    -> mkLets (bindings <> newBindings) e'+    NSet recur bindings -> Fix $ NSet recur (bindings <> newBindings)+    _                   -> error "Can only append bindings to a set or a let" --- | Applies a transformation to the body of a nix function.+-- | Applies a transformation to the body of a Nix function. modifyFunctionBody :: (NExpr -> NExpr) -> NExpr -> NExpr-modifyFunctionBody f (Fix (NAbs params body)) = Fix $ NAbs params $ f body+modifyFunctionBody transform (Fix (NAbs params body)) = mkFunction params $ transform body modifyFunctionBody _ _ = error "Not a function" --- | A let statement with multiple assignments.+-- | A @let@ statement with multiple assignments. letsE :: [(Text, NExpr)] -> NExpr -> NExpr-letsE pairs = Fix . NLet (uncurry bindTo <$> pairs)+letsE pairs = mkLets $ uncurry ($=) <$> pairs  -- | Wrapper for a single-variable @let@. letE :: Text -> NExpr -> NExpr -> NExpr-letE varName varExpr = letsE [(varName, varExpr)]+letE varName varExpr = letsE $ one (varName, varExpr) --- | Make an attribute set (non-recursive).+-- | Make a non-recursive attribute set. attrsE :: [(Text, NExpr)] -> NExpr-attrsE pairs = Fix $ NSet NNonRecursive $ uncurry bindTo <$> pairs+attrsE pairs = mkNonRecSet $ uncurry ($=) <$> pairs --- | Make an attribute set (recursive).+-- | Make a recursive attribute set. recAttrsE :: [(Text, NExpr)] -> NExpr-recAttrsE pairs = Fix $ NSet NRecursive $ uncurry bindTo <$> pairs+recAttrsE pairs = mkRecSet $ uncurry ($=) <$> pairs --- | Logical negation.-mkNot :: NExpr -> NExpr-mkNot = Fix . NUnary NNot --- -- | Dot-reference into an attribute set.--- (!.) :: NExpr -> Text -> NExpr--- (!.) = mkDot--- infixl 8 !.- -- * Nix binary operators --- | Nix binary operator builder.-mkBinop :: NBinaryOp -> NExpr -> NExpr -> NExpr-mkBinop op e1 e2 = Fix $ NBinary op e1 e2- (@@), ($==), ($!=), ($<), ($<=), ($>), ($>=), ($&&), ($||), ($->), ($//), ($+), ($-), ($*), ($/), ($++)   :: 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+(@.) = getRefOrDefault 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+(@.<|>) obj name alt = getRefOrDefault (pure alt ) obj name+infix 9 @.<|>+ -- | Function application (@' '@ in @f x@)-(@@) = mkBinop NApp-infixl 1 @@--- | Equality: @==@-($==) = mkBinop NEq--- | Inequality: @!=@-($!=) = mkBinop NNEq--- | Less than: @<@-($<)  = mkBinop NLt--- | Less than OR equal: @<=@-($<=) = mkBinop NLte+(@@) = mkOp2 NApp+infixl 8 @@++-- | List concatenation: @++@+($++) = mkOp2 NConcat+infixr 7 $++++-- | Multiplication: @*@+($*)  = mkOp2 NMult+infixl 6 $*++-- | Division: @/@+($/)  = mkOp2 NDiv+infixl 6 $/++-- | Addition: @+@+($+)  = mkOp2 NPlus+infixl 5 $+++-- | Subtraction: @-@+($-)  = mkOp2 NMinus+infixl 5 $-++-- | Extend/override the left attr set, with the right one: @//@+($//) = mkOp2 NUpdate+infixr 5 $//+ -- | Greater than: @>@-($>)  = mkBinop NGt+($>)  = mkOp2 NGt+infix 4 $>+ -- | Greater than OR equal: @>=@-($>=) = mkBinop NGte+infix 4 $>=+($>=) = mkOp2 NGte++-- | Less than OR equal: @<=@+($<=) = mkOp2 NLte+infix 4 $<=++-- | Less than: @<@+($<)  = mkOp2 NLt+infix 4 $<++-- | Equality: @==@+($==) = mkOp2 NEq+infix 3 $==++-- | Inequality: @!=@+($!=) = mkOp2 NNEq+infix 3 $!=+ -- | AND: @&&@-($&&) = mkBinop NAnd+($&&) = mkOp2 NAnd+infixl 2 $&&+ -- | OR: @||@-($||) = mkBinop NOr--- | Logical implication: @->@-($->) = mkBinop NImpl--- | Extend/override the left attr set, with the right one: @//@-($//) = mkBinop NUpdate--- | Addition: @+@-($+)  = mkBinop NPlus--- | Subtraction: @-@-($-)  = mkBinop NMinus--- | Multiplication: @*@-($*)  = mkBinop NMult--- | Division: @/@-($/)  = mkBinop NDiv--- | List concatenation: @++@-($++) = mkBinop NConcat+($||) = mkOp2 NOr+infixl 2 $|| +-- | Logical implication: @->@+($->) = mkOp2 NImpl+infix 1 $-> --- | Lambda function.--- > x ==> x---Haskell:--- > \\ x -> x---Nix:--- > x: x+-- | Lambda function, analog of Haskell's @\\ x -> x@:+--+-- +---------------+-----------++-- | Haskell       | Nix       |+-- +===============+===========++-- | @x ==> expr @ | @x: expr@ |+-- +---------------+-----------+ (==>) :: Params NExpr -> NExpr -> NExpr (==>) = mkFunction infixr 1 ==> --- | Dot-reference into an attribute set: @attrSet.k@-(@.) :: NExpr -> Text -> NExpr-(@.) obj name = Fix $ NSelect obj (StaticKey name :| mempty) Nothing-infixl 2 @.++-- * Under deprecation++-- NOTE: Remove after 2023-07+-- | __@Deprecated@__: Please, use `mkOp`+-- Put an unary operator.+mkOper :: NUnaryOp -> NExpr -> NExpr+mkOper op = Fix . NUnary op++-- NOTE: Remove after 2023-07+-- | __@Deprecated@__: Please, use `mkOp2`+-- | Put a binary operator.+mkOper2 :: NBinaryOp -> NExpr -> NExpr -> NExpr+mkOper2 op a = Fix . NBinary op a++-- NOTE: Remove after 2023-07+-- | __@Deprecated@__: Please, use `mkOp2`+-- | Nix binary operator builder.+mkBinop :: NBinaryOp -> NExpr -> NExpr -> NExpr+mkBinop = 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 params variadic = ParamSet Nothing (Variadic `whenTrue` variadic) (coerce params)
src/Nix/Expr/Strings.hs view
@@ -2,7 +2,6 @@ -- | Functions for manipulating nix strings. module Nix.Expr.Strings where -import           Nix.Utils import           Relude.Unsafe                 as Unsafe -- Please, switch things to NonEmpty import           Data.List                      ( dropWhileEnd@@ -10,7 +9,7 @@                                                 , lookup                                                 ) import qualified Data.Text                     as T-import           Nix.Expr+import           Nix.Expr.Types  -- | Merge adjacent @Plain@ values with @<>@. mergePlain :: [Antiquoted Text r] -> [Antiquoted Text r]@@ -22,8 +21,8 @@  -- | Remove 'Plain' values equal to 'mempty', as they don't have any -- informational content.-removePlainEmpty :: [Antiquoted Text r] -> [Antiquoted Text r]-removePlainEmpty = filter f where+removeEmptyPlains :: [Antiquoted Text r] -> [Antiquoted Text r]+removeEmptyPlains = filter f where   f (Plain x) = x /= mempty   f _         = True @@ -42,17 +41,18 @@ -- | Split a stream representing a string with antiquotes on line breaks. splitLines :: [Antiquoted Text r] -> [[Antiquoted Text r]] splitLines = uncurry (flip (:)) . go where-  go (Plain t : xs) = (Plain l :) <$> foldr f (go xs) ls   where+  go (Plain t : xs) = (Plain l :) <$> foldr f (go xs) ls+   where     (l : ls) = T.split (== '\n') t     f prefix (finished, current) = ((Plain prefix : current) : finished, mempty)   go (Antiquoted a   : xs) = (Antiquoted a :) <$> go xs   go (EscapedNewline : xs) = (EscapedNewline :) <$> go xs-  go []                    = (mempty, mempty)+  go []                    = mempty  -- | Join a stream of strings containing antiquotes again. This is the inverse -- of 'splitLines'. unsplitLines :: [[Antiquoted Text r]] -> [Antiquoted Text r]-unsplitLines = intercalate [Plain "\n"]+unsplitLines = intercalate $ one $ Plain "\n"  -- | Form an indented string by stripping spaces equal to the minimal indent. stripIndent :: [Antiquoted Text r] -> NString r@@ -60,7 +60,7 @@ stripIndent xs =   Indented     minIndent-    (removePlainEmpty $+    (removeEmptyPlains $       mergePlain $         (snd <$>) $           dropWhileEnd@@ -111,7 +111,7 @@   [('\n', 'n'), ('\r', 'r'), ('\t', 't'), ('\\', '\\'), ('$', '$'), ('"', '"')]  fromEscapeCode :: Char -> Maybe Char-fromEscapeCode = (`lookup` fmap swap escapeCodes)+fromEscapeCode = (`lookup` (swap <$> escapeCodes))  toEscapeCode :: Char -> Maybe Char toEscapeCode = (`lookup` escapeCodes)
src/Nix/Expr/Types.hs view
@@ -1,40 +1,38 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}+{-# language ConstraintKinds #-}+{-# language CPP #-}+{-# language DeriveAnyClass #-}+{-# language FunctionalDependencies #-}+{-# language RankNTypes #-}+{-# language TemplateHaskell #-}+{-# language TypeFamilies #-} -{-# OPTIONS_GHC -Wno-orphans #-}-{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# options_ghc -Wno-orphans #-}+{-# options_ghc -Wno-missing-signatures #-}  -- | The Nix expression type and supporting types. ----- For a brief introduction of the Nix expression language, see--- <https://nixos.org/nix/manual/#ch-expression-language>.+-- [Brief introduction of the Nix expression language.](https://nixos.org/nix/manual/#ch-expression-language) -- -- This module is a beginning of a deep embedding (term) of a Nix language into Haskell.--- Shallow/deep embedding brief:--- <https://web.archive.org/web/20201112031804/https://alessandrovermeulen.me/2013/07/13/the-difference-between-shallow-and-deep-embedding/>+-- [Brief on shallow & deep embedding.](https://web.archive.org/web/20201112031804/https://alessandrovermeulen.me/2013/07/13/the-difference-between-shallow-and-deep-embedding/) ----- (additiona info for dev): Big use of TemplateHaskell in the module requires proper (top-down) organization of declarations+-- (additiona info for dev): Big use of TemplateHaskell in the module requires proper (top-down) organization of declarations. module Nix.Expr.Types where  import qualified Codec.Serialise                as Serialise import           Codec.Serialise                ( Serialise )-import           Control.DeepSeq+import           Control.DeepSeq                ( NFData1(..) ) import           Data.Aeson-import           Data.Aeson.TH import qualified Data.Binary                   as Binary import           Data.Binary                    ( Binary ) import           Data.Data-import           Data.Fix+import           Data.Fix                       ( Fix(Fix) ) import           Data.Functor.Classes import           Data.Hashable.Lifted+import qualified Data.HashMap.Lazy             as MapL import qualified Data.List.NonEmpty            as NE import qualified Text.Show-import           Data.Traversable+import           Data.Traversable               ( fmapDefault, foldMapDefault ) import           GHC.Generics import qualified Language.Haskell.TH.Syntax    as TH import           Lens.Family2@@ -44,22 +42,31 @@                                                 , mkPos                                                 , unPos                                                 )-import           Text.Show.Deriving-import           Text.Read.Deriving-import           Data.Eq.Deriving-import           Data.Ord.Deriving+import           Text.Show.Deriving             ( deriveShow1, deriveShow2 )+import           Text.Read.Deriving             ( deriveRead1, deriveRead2 )+import           Data.Eq.Deriving               ( deriveEq1  , deriveEq2   )+import           Data.Ord.Deriving              ( deriveOrd1 , deriveOrd2  )+import           Data.Aeson.TH                  ( deriveJSON2 ) import qualified Type.Reflection               as Reflection-import           Type.Reflection                ( eqTypeRep ) import           Nix.Atoms-import           Nix.Utils #if !MIN_VERSION_text(1,2,4) -- NOTE: Remove package @th-lift-instances@ removing this-import           Instances.TH.Lift              ()  -- importing Lift Text fo GHC 8.6+import           Instances.TH.Lift              ()  -- importing Lift Text for GHC 8.6 #endif  --- * Utilitary: orphan instances+-- * utils +-- | Holds file positionng information for abstrations.+-- A type synonym for @HashMap VarName SourcePos@.+type PositionSet = HashMap VarName SourcePos++--  2021-07-16: NOTE: Should replace @ParamSet@ List+-- | > Hashmap VarName -- type synonym+type AttrSet = HashMap VarName++-- ** orphan instances+ -- Placed here because TH inference depends on declaration sequence.  -- Upstreaming so far was not pursued.@@ -102,24 +109,53 @@   parseJSON = fmap mkPos . parseJSON instance FromJSON SourcePos - -- * Components of Nix expressions  -- NExpr is a composition of---   * direct reuse of the Haskell types (list, FilePath, Text)+--   * direct reuse of the Haskell types (list, Path, Text) --   * NAtom --   * Types in this section --   * Fixpoint nature -type VarName = Text+-- ** newtype VarName +newtype VarName = VarName Text+  deriving+    ( Eq, Ord, Generic+    , Typeable, Data, NFData, Serialise, Binary, ToJSON, FromJSON+    , Show, Read, Hashable+    ) --- ** @Params@+instance IsString VarName where+  fromString = coerce . fromString @Text +instance ToString VarName where+  toString = toString @Text . coerce++-- ** data Params++-- *** utils+ -- This uses an association list because nix XML serialization preserves the -- order of the param set. type ParamSet r = [(VarName, Maybe r)] +data Variadic = Closed | Variadic+  deriving+    ( Eq, Ord, Generic+    , Typeable, Data, NFData, Serialise, Binary, ToJSON, FromJSON+    , Show, Read, Hashable+    )++instance Semigroup Variadic where+  (<>) Closed Closed = Closed+  (<>) _      _      = Variadic++instance Monoid Variadic where+  mempty = Closed++-- *** data Params+ -- | @Params@ represents all the ways the formal parameters to a -- function can be represented. data Params r@@ -127,20 +163,18 @@   -- ^ For functions with a single named argument, such as @x: x + 1@.   --   -- > Param "x"                                  ~  x-  | ParamSet !(ParamSet r) !Bool !(Maybe VarName)-  --  2021-05-15: NOTE: Seems like we should flip the ParamSet, so partial application kicks in for Bool?-  --  2021-05-15: NOTE: '...' variadic property probably needs a Bool synonym.+  | ParamSet !(Maybe VarName) !Variadic !(ParamSet r)   -- ^ Explicit parameters (argument must be a set). Might specify a name to   -- bind to the set in the function body. The bool indicates whether it is   -- variadic or not.   ---  -- > ParamSet [("x",Nothing)] False Nothing     ~  { x }-  -- > ParamSet [("x",pure y)]  True  (pure "s")  ~  s@{ x ? y, ... }+  -- > ParamSet  Nothing   False [("x",Nothing)]  ~  { x }+  -- > ParamSet (pure "s") True  [("x", pure y)]  ~  s@{ x ? y, ... }   deriving     ( Eq, Ord, Generic, Generic1     , Typeable, Data, NFData, NFData1, Serialise, Binary, ToJSON, ToJSON1, FromJSON, FromJSON1     , Functor, Foldable, Traversable-    , Show, Hashable+    , Show, Hashable, Hashable1     )  instance IsString (Params r) where@@ -151,14 +185,12 @@ $(deriveEq1   ''Params) $(deriveOrd1  ''Params) -deriving instance Hashable1 Params---- *** Lens traversals+-- *** lens traversals  $(makeTraversals ''Params)  --- ** @Antiquoted@+-- ** data Antiquoted  -- | 'Antiquoted' represents an expression that is either -- antiquoted (surrounded by ${...}) or plain (not antiquoted).@@ -178,7 +210,7 @@     , Typeable, Data, NFData, NFData1, Serialise, Binary     , ToJSON, ToJSON1, FromJSON, FromJSON1     , Functor, Foldable, Traversable-    , Show, Read, Hashable+    , Show, Read, Hashable, Hashable1     )  instance Hashable2 Antiquoted where@@ -196,26 +228,25 @@ $(deriveOrd2  ''Antiquoted) $(deriveJSON2 defaultOptions ''Antiquoted) -deriving instance Hashable v => Hashable1 (Antiquoted v) --- *** Lens traversals+-- *** lens traversals  $(makeTraversals ''Antiquoted)  --- ** @NString@+-- ** data NString  -- | An 'NString' is a list of things that are either a plain string -- or an antiquoted expression. After the antiquotes have been evaluated, -- the final string is constructed by concatenating all the parts. data NString r   = DoubleQuoted ![Antiquoted Text r]-  -- ^ Strings wrapped with double-quotes (") can contain literal newline+  -- ^ Strings wrapped with double-quotes (__@"@__) can contain literal newline   -- characters, but the newlines are preserved and no indentation is stripped.   --   -- > DoubleQuoted [Plain "x",Antiquoted y]   ~  "x${y}"   | Indented !Int ![Antiquoted Text r]-  -- ^ Strings wrapped with two single quotes ('') can contain newlines, and+  -- ^ Strings wrapped with two single quotes (__@''@__) can contain newlines, and   --   their indentation will be stripped, but the amount stripped is   --   remembered.   --@@ -230,27 +261,25 @@     ( Eq, Ord, Generic, Generic1     , Typeable, Data, NFData, NFData1, Serialise, Binary, ToJSON, ToJSON1, FromJSON, FromJSON1     , Functor, Foldable, Traversable-    , Show, Read, Hashable+    , Show, Read, Hashable, Hashable1     )  -- | For the the 'IsString' instance, we use a plain doublequoted string. instance IsString (NString r) where   fromString ""     = DoubleQuoted mempty-  fromString string = DoubleQuoted [Plain $ toText string]+  fromString string = DoubleQuoted [Plain $ fromString string]  $(deriveShow1 ''NString) $(deriveRead1 ''NString) $(deriveEq1   ''NString) $(deriveOrd1  ''NString) -deriving instance Hashable1 NString---- *** Lens traversals+-- *** lens traversals  $(makeTraversals ''NString)  --- ** @NKeyName@+-- ** data NKeyName  -- | A 'KeyName' is something that can appear on the left side of an -- equals sign. For example, @a@ is a 'KeyName' in @{ a = 3; }@, @let a = 3;@@ -318,11 +347,12 @@ -- occurs not only as last argument in @Antiquoted (NString r) r@ instance Show1 NKeyName where   liftShowsPrec sp sl p = \case-    DynamicKey a -> showsUnaryWith-      (liftShowsPrec2 (liftShowsPrec sp sl) (liftShowList sp sl) sp sl)-      "DynamicKey"-      p-      a+    DynamicKey a ->+      showsUnaryWith+        (liftShowsPrec2 (liftShowsPrec sp sl) (liftShowList sp sl) sp sl)+        "DynamicKey"+        p+        a     StaticKey t -> showsUnaryWith Text.Show.showsPrec "StaticKey" p t  -- Deriving this instance automatically is not possible because @r@@@ -344,12 +374,12 @@     DynamicKey EscapedNewline   -> pure $ DynamicKey EscapedNewline     StaticKey  key              -> pure $ StaticKey key --- *** Lens traversals+-- *** lens traversals  $(makeTraversals ''NKeyName)  --- ** @NAttrPath@+-- ** type NAttrPath  -- | A selector (for example in a @let@ or an attribute set) is made up -- of strung-together key names.@@ -358,7 +388,7 @@ type NAttrPath r = NonEmpty (NKeyName r)  --- ** @Binding@+-- ** data Binding  #if !MIN_VERSION_hashable(1,3,1) -- Required by Hashable Binding deriving. There was none of this Hashable instance before mentioned version, remove this in year >2022@@ -371,7 +401,7 @@   -- ^ An explicit naming.   --   -- > NamedVar (StaticKey "x" :| [StaticKey "y"]) z SourcePos{}  ~  x.y = z;-  | Inherit !(Maybe r) ![NKeyName r] !SourcePos+  | Inherit !(Maybe r) ![VarName] !SourcePos   -- ^ Inheriting an attribute (binding) into the attribute set from the other scope (attribute set). No denoted scope means to inherit from the closest outside scope.   --   -- +---------------------------------------------------------------+--------------------+-----------------------+@@ -391,7 +421,7 @@     ( Eq, Ord, Generic, Generic1     , Typeable, Data, NFData, NFData1, Serialise, Binary, ToJSON, FromJSON     , Functor, Foldable, Traversable-    , Show, Hashable+    , Show, Hashable, Hashable1     )  $(deriveShow1 ''Binding)@@ -399,29 +429,33 @@ $(deriveOrd1  ''Binding) --x $(deriveJSON1 defaultOptions ''Binding) -deriving instance Hashable1 Binding---- *** Lens traversals+-- *** lens traversals  $(makeTraversals ''Binding)  --- ** @NRecordType@+-- ** data Recursivity --- | 'NRecordType' distinguishes between recursive and non-recursive attribute+-- | Distinguishes between recursive and non-recursive. Mainly for attribute -- sets.-data NRecordType-  = NNonRecursive  -- ^ >     { ... }-  | NRecursive     -- ^ > rec { ... }+data Recursivity+  = NonRecursive  -- ^ >     { ... }+  | Recursive     -- ^ > rec { ... }   deriving     ( Eq, Ord, Enum, Bounded, Generic     , Typeable, Data, NFData, Serialise, Binary, ToJSON, FromJSON     , Show, Read, Hashable     ) +instance Semigroup Recursivity where+  (<>) NonRecursive NonRecursive = NonRecursive+  (<>) _ _ = Recursive --- ** @NUnaryOp@+instance Monoid Recursivity where+  mempty = NonRecursive +-- ** data NUnaryOp+ -- | There are two unary operations: logical not and integer negation. data NUnaryOp   = NNeg  -- ^ @-@@@ -432,12 +466,12 @@     , Show, Read, Hashable     ) --- *** Lens traversals+-- *** lens traversals  $(makeTraversals ''NUnaryOp)  --- ** @NBinaryOp@+-- ** data NBinaryOp  -- | Binary operators expressible in the nix language. data NBinaryOp@@ -465,12 +499,12 @@     , Show, Read, Hashable     ) --- *** Lens traversals+-- *** lens traversals  $(makeTraversals ''NBinaryOp)  --- ** @NExprF@ - Nix expressions, base functor+-- * data NExprF - Nix expressions, base functor  -- | The main Nix expression type. As it is polimophic, has a functor, -- which allows to traverse expressions and map functions over them.@@ -490,19 +524,19 @@   -- ^ A list literal.   --   -- > NList [x,y]                                 ~  [ x y ]-  | NSet !NRecordType ![Binding r]+  | NSet !Recursivity ![Binding r]   -- ^ An attribute set literal   ---  -- > NSet NRecursive    [NamedVar x y _]         ~  rec { x = y; }-  -- > NSet NNonRecursive [Inherit Nothing [x] _]  ~  { inherit x; }-  | NLiteralPath !FilePath+  -- > NSet Recursive    [NamedVar x y _]         ~  rec { x = y; }+  -- > NSet NonRecursive [Inherit Nothing [x] _]  ~  { inherit x; }+  | NLiteralPath !Path   -- ^ A path expression, which is evaluated to a store path. The path here   -- can be relative, in which case it's evaluated relative to the file in   -- which it appears.   --   -- > NLiteralPath "/x"                           ~  /x   -- > NLiteralPath "x/y"                          ~  x/y-  | NEnvPath !FilePath+  | NEnvPath !Path   -- ^ A path which refers to something in the Nix search path (the NIX_PATH   -- environment variable. For example, @<nixpkgs/pkgs>@.   --@@ -517,14 +551,12 @@   --   -- > NBinary NPlus x y                           ~  x + y   -- > NBinary NApp  f x                           ~  f x-  | NSelect !r !(NAttrPath r) !(Maybe r)-  --  2021-05-15: NOTE: Default value should be first argument to leverage partial application.-  -- Cascading change diff is not that big.+  | NSelect !(Maybe r) !r !(NAttrPath r)   -- ^ Dot-reference into an attribute set, optionally providing an   -- alternative if the key doesn't exist.   ---  -- > NSelect s (x :| []) Nothing                 ~  s.x-  -- > NSelect s (x :| []) (pure y)                ~  s.x or y+  -- > NSelect Nothing  s (x :| [])                ~  s.x+  -- > NSelect (pure y) s (x :| [])                ~  s.x or y   | NHasAttr !r !(NAttrPath r)   -- ^ Ask if a set contains a given attribute path.   --@@ -549,7 +581,7 @@   --   -- > NWith x y                                   ~  with x; y   | NAssert !r !r-  -- ^ Assert that the first returns @true@ before evaluating the second.+  -- ^ Checks that the first argument is a predicate that is @true@ before evaluating the second argument.   --   -- > NAssert x y                                 ~  assert x; y   | NSynHole !VarName@@ -562,7 +594,7 @@     ( Eq, Ord, Generic, Generic1     , Typeable, Data, NFData, NFData1, Serialise, Binary, ToJSON, FromJSON     , Functor, Foldable, Traversable-    , Show, Hashable+    , Show, Hashable, Hashable1     )  @@ -571,14 +603,12 @@ $(deriveOrd1  ''NExprF) --x $(deriveJSON1 defaultOptions ''NExprF) -deriving instance Hashable1 NExprF---- *** Lens traversals+-- ** lens traversals  $(makeTraversals ''NExprF)  --- *** @NExpr@+-- ** type NExpr  -- | The monomorphic expression type is a fixed point of the polymorphic one. type NExpr = Fix NExprF@@ -600,13 +630,13 @@           -- Reflection is a key strategy in metaprogramming.           -- <https://en.wikipedia.org/wiki/Reflective_programming>           HRefl <--            eqTypeRep+            Reflection.eqTypeRep               (Reflection.typeRep @Text)               (Reflection.typeOf  b    )           pure [| $(TH.lift b) |]       ) #if MIN_VERSION_template_haskell(2,17,0)-  liftTyped = TH.liftTyped+  liftTyped = TH.unsafeCodeCoerce . TH.lift #elif MIN_VERSION_template_haskell(2,16,0)   liftTyped = TH.unsafeTExpCoerce . TH.lift #endif@@ -624,31 +654,47 @@ #else hashAt :: VarName -> Lens' (AttrSet v) (Maybe v) #endif-hashAt = flip alterF+hashAt = alterF+ where+  alterF+    :: (Functor f)+    => VarName+    -> (Maybe v -> f (Maybe v))+    -> AttrSet v+    -> f (AttrSet v)+  alterF (coerce -> k) f m =+    maybe+      (MapL.delete k m)+      (\ v -> MapL.insert k v m)+      <$> f (MapL.lookup k m)  -- | Get the name out of the parameter (there might be none). paramName :: Params r -> Maybe VarName-paramName (Param n       ) = pure n-paramName (ParamSet _ _ n) = n+paramName (Param name        ) = pure name+paramName (ParamSet mname _ _) = mname +stringParts :: NString r -> [Antiquoted Text r]+stringParts (DoubleQuoted parts) = parts+stringParts (Indented _   parts) = parts+ stripPositionInfo :: NExpr -> NExpr stripPositionInfo = transport phi  where   transport f (Fix x) = Fix $ transport f <$> f x -  phi (NSet recur binds) = NSet recur $ go <$> binds-  phi (NLet binds body) = NLet (go <$> binds) body+  phi (NSet recur binds) = NSet recur $ erasePositions <$> binds+  phi (NLet binds body) = NLet (erasePositions <$> binds) body   phi x                 = x -  go (NamedVar path r     _pos) = NamedVar path r     nullPos-  go (Inherit  ms   names _pos) = Inherit  ms   names nullPos+  erasePositions (NamedVar path r     _pos) = NamedVar path r     nullPos+  erasePositions (Inherit  ms   names _pos) = Inherit  ms   names nullPos  nullPos :: SourcePos nullPos = on (SourcePos "<string>") mkPos 1 1  -- * Dead code --- ** @class NExprAnn@+-- ** class NExprAnn  class NExprAnn ann g | g -> ann where   fromNExpr :: g r -> (NExprF r, ann)@@ -657,37 +703,39 @@ -- ** Other  ekey-  :: NExprAnn ann g-  => NonEmpty Text+  :: forall ann g+  . NExprAnn ann g+  => NonEmpty VarName   -> SourcePos   -> Lens' (Fix g) (Maybe (Fix g))-ekey keys pos f e@(Fix x) | (NSet NNonRecursive xs, ann) <- fromNExpr x =-  case go xs of-    ((v, []      ) : _) -> fromMaybe e <$> f (pure v)-    ((v, r : rest) : _) -> ekey (r :| rest) pos f v+ekey keys pos f e@(Fix x)+  | (NSet NonRecursive xs, ann) <- fromNExpr x =+    let+      vals :: [(Fix g, [VarName])]+      vals =+        do+          let keys' = NE.toList keys+          (ks, rest) <- zip (inits keys') (tails keys')+          list+            mempty+            (\ (j : js) ->+              do+                NamedVar ns v _p <- xs+                guard $ (j : js) == (NE.toList ns ^.. traverse . _StaticKey)+                pure (v, rest)+            )+            ks+    in+    case vals of+      ((v, []      ) : _) -> fromMaybe e <$> f (pure v)+      ((v, r : rest) : _) -> ekey (r :| rest) pos f v -    _                   ->-      maybe-        e-        (\ v ->-          let entry = NamedVar (StaticKey <$> keys) v pos in-          Fix $ toNExpr ( NSet NNonRecursive $ [entry] <> xs, ann )-        )-      <$>-        f Nothing-  where-    go xs =-      do-        let keys' = NE.toList keys-        (ks, rest) <- zip (inits keys') (tails keys')-        list-          mempty-          (\ (j : js) ->-            do-              NamedVar ns v _p <- xs-              guard $ (j : js) == (NE.toList ns ^.. traverse . _StaticKey)-              pure (v, rest)+      _                   ->+        maybe+          e+          (\ v ->+            let entry = NamedVar (StaticKey <$> keys) v pos in+            Fix $ toNExpr ( NSet mempty $ one entry <> xs, ann )           )-          ks-+        <$> f Nothing ekey _ _ f e = fromMaybe e <$> f Nothing
src/Nix/Expr/Types/Annotated.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE CPP                #-}-{-# LANGUAGE DeriveAnyClass     #-}-{-# LANGUAGE KindSignatures     #-}-{-# LANGUAGE PatternSynonyms    #-}-{-# LANGUAGE RankNTypes         #-}-{-# LANGUAGE TemplateHaskell    #-}+{-# language CPP                #-}+{-# language DeriveAnyClass     #-}+{-# language KindSignatures     #-}+{-# language PatternSynonyms    #-}+{-# language RankNTypes         #-}+{-# language TemplateHaskell    #-}  -- | The source location annotated nix expression type and supporting types. --@@ -26,7 +26,8 @@ import           Data.Data import           Data.Eq.Deriving import           Data.Fix                       ( Fix(..)-                                                , unfoldFix )+                                                , unfoldFix+                                                ) import           Data.Functor.Compose import           Data.Hashable.Lifted import           Data.Ord.Deriving@@ -44,18 +45,18 @@  -- | Demarcation of a chunk in a source file. data SrcSpan = SrcSpan-    { spanBegin :: SourcePos-    , spanEnd   :: SourcePos-    }-    deriving (Ord, Eq, Generic, Typeable, Data, Show, NFData, Hashable)+  { spanBegin :: SourcePos+  , spanEnd   :: SourcePos+  }+ deriving (Ord, Eq, Generic, Typeable, Data, Show, NFData, Hashable)  -- ** Instances  instance Semigroup SrcSpan where   s1 <> s2 =     SrcSpan-      ((min `on` spanBegin) s1 s2)-      ((max `on` spanEnd  ) s1 s2)+      (on min spanBegin s1 s2)+      (on max spanEnd   s1 s2)  instance Binary SrcSpan instance ToJSON SrcSpan@@ -65,70 +66,78 @@  -- * data type @Ann@ +--  2021-08-02: NOTE: Annotation needs to be after what is annotated. -- | A type constructor applied to a type along with an annotation -- -- Intended to be used with 'Fix':--- @type MyType = Fix (Compose (Ann Annotation) F)@-data Ann ann a = Ann-    { annotation :: ann-    , annotated  :: a-    }-    deriving (Ord, Eq, Data, Generic, Generic1, Typeable, Functor, Foldable,-              Traversable, Read, Show, NFData, Hashable)+-- @type MyType = Fix (Compose (AnnUnit Annotation) F)@+data AnnUnit ann expr = AnnUnit+  { annotation :: ann+  , annotated  :: expr+  }+ deriving+  ( Eq, Ord, Data, Typeable, Hashable+  , Generic, Generic1, NFData+  , Functor, Foldable, Traversable+  , Show, Read+  ) -type AnnF ann f = Compose (Ann ann) f+type AnnF ann f = Compose (AnnUnit ann) f --- | Pattern: @(Compose (Ann _ _))@.-pattern AnnFP+-- | Pattern: @(Compose (AnnUnit _ _))@.+pattern AnnF   :: ann   -> f a-  -> Compose (Ann ann) f a-pattern AnnFP ann f = Compose (Ann ann f)-{-# complete AnnFP #-}+  -> Compose (AnnUnit ann) f a+pattern AnnF ann f = Compose (AnnUnit ann f)+{-# complete AnnF #-} --- | Pattern: @Fix (Compose (Ann _ _))@.++type Ann ann f = Fix (AnnF ann f)++-- | Pattern: @Fix (Compose (AnnUnit _ _))@. -- Fix composes units of (annotations & the annotated) into one object. -- Giving annotated expression.-pattern AnnE+pattern Ann   :: forall ann (f :: Type -> Type)   . ann-  -> f (Fix (AnnF ann f))-  -> Fix (AnnF ann f)-pattern AnnE ann a = Fix (AnnFP ann a)-{-# complete AnnE #-}+  -> f (Ann ann f)+  -> Ann ann f+pattern Ann ann a = Fix (AnnF ann a)+{-# complete Ann #-} -annToAnnF :: Ann ann (f (Fix (AnnF ann f))) -> Fix (AnnF ann f)-annToAnnF (Ann ann a) = AnnE ann a+annUnitToAnn :: AnnUnit ann (f (Ann ann f)) -> Ann ann f+annUnitToAnn (AnnUnit ann a) = Ann ann a  -- ** Instances -instance Hashable ann => Hashable1 (Ann ann)+instance Hashable ann => Hashable1 (AnnUnit ann) -instance NFData ann => NFData1 (Ann ann)+instance NFData ann => NFData1 (AnnUnit ann) -instance (Binary ann, Binary a) => Binary (Ann ann a)+instance (Binary ann, Binary a) => Binary (AnnUnit ann a) -$(deriveEq1   ''Ann)-$(deriveEq2   ''Ann)-$(deriveOrd1  ''Ann)-$(deriveOrd2  ''Ann)-$(deriveRead1 ''Ann)-$(deriveRead2 ''Ann)-$(deriveShow1 ''Ann)-$(deriveShow2 ''Ann)-$(deriveJSON1 defaultOptions ''Ann)-$(deriveJSON2 defaultOptions ''Ann)+$(deriveEq1   ''AnnUnit)+$(deriveEq2   ''AnnUnit)+$(deriveOrd1  ''AnnUnit)+$(deriveOrd2  ''AnnUnit)+$(deriveRead1 ''AnnUnit)+$(deriveRead2 ''AnnUnit)+$(deriveShow1 ''AnnUnit)+$(deriveShow2 ''AnnUnit)+$(deriveJSON1 defaultOptions ''AnnUnit)+$(deriveJSON2 defaultOptions ''AnnUnit) -instance (Serialise ann, Serialise a) => Serialise (Ann ann a)+instance (Serialise ann, Serialise a) => Serialise (AnnUnit ann a)  -- ** @NExprLoc{,F}@ - annotated Nix expression  type NExprLocF = AnnF SrcSpan NExprF  instance Serialise r => Serialise (NExprLocF r) where-  encode (AnnFP ann a) = encode ann <> encode a+  encode (AnnF ann a) = encode ann <> encode a   decode =-    liftA2 AnnFP+    liftA2 AnnF       decode       decode @@ -143,105 +152,150 @@  -- * Other -stripAnnotation :: Functor f => Fix (AnnF ann f) -> Fix f-stripAnnotation = unfoldFix (stripAnn . unFix)+stripAnnF :: AnnF ann f r -> f r+stripAnnF = annotated . getCompose -stripAnn :: AnnF ann f r -> f r-stripAnn = annotated . getCompose+stripAnnotation :: Functor f => Ann ann f -> Fix f+stripAnnotation = unfoldFix (stripAnnF . unFix) -nUnary :: Ann SrcSpan NUnaryOp -> NExprLoc -> NExprLoc-nUnary (Ann s1 u) e1@(AnnE s2 _) = AnnE (s1 <> s2) $ NUnary u e1-{-# inline nUnary #-}+annNUnary :: AnnUnit SrcSpan NUnaryOp -> NExprLoc -> NExprLoc+annNUnary (AnnUnit s1 u) e1@(Ann s2 _) = NUnaryAnn (s1 <> s2) u e1+{-# inline annNUnary #-} -nBinary :: Ann SrcSpan NBinaryOp -> NExprLoc -> NExprLoc -> NExprLoc-nBinary (Ann s1 b) e1@(AnnE s2 _) e2@(AnnE s3 _) =-  AnnE (s1 <> s2 <> s3) $ NBinary b e1 e2+annNBinary :: AnnUnit SrcSpan NBinaryOp -> NExprLoc -> NExprLoc -> NExprLoc+annNBinary (AnnUnit s1 b) e1@(Ann s2 _) e2@(Ann s3 _) = NBinaryAnn (s1 <> s2 <> s3) b e1 e2 -nSelectLoc-  :: NExprLoc -> Ann SrcSpan (NAttrPath NExprLoc) -> Maybe NExprLoc -> NExprLoc-nSelectLoc e1@(AnnE s1 _) (Ann s2 ats) =-  --  2021-05-16: NOTE: This could been rewritten into function application of @(s3, pure e2)@-  -- if @SrcSpan@ was Monoid, which requires @SorcePos@ to be a Monoid, and upstream code prevents it.-  -- Question upstream: https://github.com/mrkkrp/megaparsec/issues/450-  maybe-    (                    AnnE  s1s2        $ NSelect e1 ats   Nothing)-    (\ e2@(AnnE s3 _) -> AnnE (s1s2 <> s3) $ NSelect e1 ats $ pure e2)- where-  s1s2 = s1 <> s2+annNSelect+  :: Maybe NExprLoc -> NExprLoc -> AnnUnit SrcSpan (NAttrPath NExprLoc) -> NExprLoc+annNSelect  Nothing             e2@(Ann s2 _) (AnnUnit s1 ats) = NSelectAnn (      s2 <> s1)  Nothing  e2 ats+annNSelect (Just e3@(Ann s3 _)) e2@(Ann s2 _) (AnnUnit s1 ats) = NSelectAnn (s3 <> s2 <> s1) (pure e3) e2 ats -nHasAttr :: NExprLoc -> Ann SrcSpan (NAttrPath NExprLoc) -> NExprLoc-nHasAttr e1@(AnnE s1 _) (Ann s2 ats) = AnnE (s1 <> s2) $ NHasAttr e1 ats+annNHasAttr :: NExprLoc -> AnnUnit SrcSpan (NAttrPath NExprLoc) -> NExprLoc+annNHasAttr e1@(Ann s1 _) (AnnUnit s2 ats) = NHasAttrAnn (s1 <> s2) e1 ats -nApp :: NExprLoc -> NExprLoc -> NExprLoc-nApp e1@(AnnE s1 _) e2@(AnnE s2 _) = AnnE (s1 <> s2) $ NBinary NApp e1 e2+annNApp :: NExprLoc -> NExprLoc -> NExprLoc+annNApp e1@(Ann s1 _) e2@(Ann s2 _) = NBinaryAnn (s1 <> s2) NApp e1 e2 -nAbs :: Ann SrcSpan (Params NExprLoc) -> NExprLoc -> NExprLoc-nAbs (Ann s1 ps) e1@(AnnE s2 _) = AnnE (s1 <> s2) $ NAbs ps e1+annNAbs :: AnnUnit SrcSpan (Params NExprLoc) -> NExprLoc -> NExprLoc+annNAbs (AnnUnit s1 ps) e1@(Ann s2 _) = NAbsAnn (s1 <> s2) ps e1 -nStr :: Ann SrcSpan (NString NExprLoc) -> NExprLoc-nStr (Ann s1 s) = AnnE s1 $ NStr s+annNStr :: AnnUnit SrcSpan (NString NExprLoc) -> NExprLoc+annNStr (AnnUnit s1 s) = NStrAnn s1 s  deltaInfo :: SourcePos -> (Text, Int, Int)-deltaInfo (SourcePos fp l c) = (toText fp, unPos l, unPos c)+deltaInfo (SourcePos fp l c) = (fromString fp, unPos l, unPos c) -nNull :: NExprLoc-nNull = AnnE nullSpan $ NConstant NNull-{-# inline nNull #-}+annNNull :: NExprLoc+annNNull = NConstantAnn nullSpan NNull+{-# inline annNNull #-}  nullSpan :: SrcSpan nullSpan = SrcSpan nullPos nullPos {-# inline nullSpan #-} --- | Pattern systems for matching on NExprLocF constructions.+-- | Pattern systems for matching on @NExprLocF@ constructions. -pattern NConstant_ :: SrcSpan -> NAtom -> NExprLocF r-pattern NConstant_ ann x = AnnFP ann (NConstant x)+pattern NConstantAnnF    :: SrcSpan -> NAtom -> NExprLocF r+pattern NConstantAnnF    ann x      = AnnF ann (NConstant x) -pattern NStr_ :: SrcSpan -> NString r -> NExprLocF r-pattern NStr_ ann x = AnnFP ann (NStr x)+pattern NStrAnnF         :: SrcSpan -> NString r -> NExprLocF r+pattern NStrAnnF         ann x      = AnnF ann (NStr x) -pattern NSym_ :: SrcSpan -> VarName -> NExprLocF r-pattern NSym_ ann x = AnnFP ann (NSym x)+pattern NSymAnnF         :: SrcSpan -> VarName -> NExprLocF r+pattern NSymAnnF         ann x      = AnnF ann (NSym x) -pattern NList_ :: SrcSpan -> [r] -> NExprLocF r-pattern NList_ ann x = AnnFP ann (NList x)+pattern NListAnnF        :: SrcSpan -> [r] -> NExprLocF r+pattern NListAnnF        ann x      = AnnF ann (NList x) -pattern NSet_ :: SrcSpan -> NRecordType -> [Binding r] -> NExprLocF r-pattern NSet_ ann recur x = AnnFP ann (NSet recur x)+pattern NSetAnnF         :: SrcSpan -> Recursivity -> [Binding r] -> NExprLocF r+pattern NSetAnnF         ann rec x  = AnnF ann (NSet rec x) -pattern NLiteralPath_ :: SrcSpan -> FilePath -> NExprLocF r-pattern NLiteralPath_ ann x = AnnFP ann (NLiteralPath x)+pattern NLiteralPathAnnF :: SrcSpan -> Path -> NExprLocF r+pattern NLiteralPathAnnF ann x      = AnnF ann (NLiteralPath x) -pattern NEnvPath_ :: SrcSpan -> FilePath -> NExprLocF r-pattern NEnvPath_ ann x = AnnFP ann (NEnvPath x)+pattern NEnvPathAnnF     :: SrcSpan -> Path -> NExprLocF r+pattern NEnvPathAnnF     ann x      = AnnF ann (NEnvPath x) -pattern NUnary_ :: SrcSpan -> NUnaryOp -> r -> NExprLocF r-pattern NUnary_ ann op x = AnnFP ann (NUnary op x)+pattern NUnaryAnnF       :: SrcSpan -> NUnaryOp -> r -> NExprLocF r+pattern NUnaryAnnF       ann op x   = AnnF ann (NUnary op x) -pattern NBinary_ :: SrcSpan -> NBinaryOp -> r -> r -> NExprLocF r-pattern NBinary_ ann op x y = AnnFP ann (NBinary op x y)+pattern NBinaryAnnF      :: SrcSpan -> NBinaryOp -> r -> r -> NExprLocF r+pattern NBinaryAnnF      ann op x y = AnnF ann (NBinary op x y) -pattern NSelect_ :: SrcSpan -> r -> NAttrPath r -> Maybe r -> NExprLocF r-pattern NSelect_ ann x p v = AnnFP ann (NSelect x p v)+pattern NSelectAnnF      :: SrcSpan ->  Maybe r -> r -> NAttrPath r -> NExprLocF r+pattern NSelectAnnF      ann v x p  = AnnF ann (NSelect v x p) -pattern NHasAttr_ :: SrcSpan -> r -> NAttrPath r -> NExprLocF r-pattern NHasAttr_ ann x p = AnnFP ann (NHasAttr x p)+pattern NHasAttrAnnF     :: SrcSpan -> r -> NAttrPath r -> NExprLocF r+pattern NHasAttrAnnF     ann x p    = AnnF ann (NHasAttr x p) -pattern NAbs_ :: SrcSpan -> Params r-> r -> NExprLocF r-pattern NAbs_ ann x b = AnnFP ann (NAbs x b)+pattern NAbsAnnF         :: SrcSpan -> Params r-> r -> NExprLocF r+pattern NAbsAnnF         ann x b    = AnnF ann (NAbs x b) -pattern NLet_ :: SrcSpan -> [Binding r] -> r -> NExprLocF r-pattern NLet_ ann x b = AnnFP ann (NLet x b)+pattern NLetAnnF         :: SrcSpan -> [Binding r] -> r -> NExprLocF r+pattern NLetAnnF         ann x b    = AnnF ann (NLet x b) -pattern NIf_ :: SrcSpan -> r -> r -> r -> NExprLocF r-pattern NIf_ ann c t e = AnnFP ann (NIf c t e)+pattern NIfAnnF          :: SrcSpan -> r -> r -> r -> NExprLocF r+pattern NIfAnnF          ann c t e  = AnnF ann (NIf c t e) -pattern NWith_ :: SrcSpan -> r -> r -> NExprLocF r-pattern NWith_ ann x y = AnnFP ann (NWith x y)+pattern NWithAnnF        :: SrcSpan -> r -> r -> NExprLocF r+pattern NWithAnnF        ann x y    = AnnF ann (NWith x y) -pattern NAssert_ :: SrcSpan -> r -> r -> NExprLocF r-pattern NAssert_ ann x y = AnnFP ann (NAssert x y)+pattern NAssertAnnF      :: SrcSpan -> r -> r -> NExprLocF r+pattern NAssertAnnF      ann x y    = AnnF ann (NAssert x y) -pattern NSynHole_ :: SrcSpan -> Text -> NExprLocF r-pattern NSynHole_ ann x = AnnFP ann (NSynHole x)-{-# complete NConstant_, NStr_, NSym_, NList_, NSet_, NLiteralPath_, NEnvPath_, NUnary_, NBinary_, NSelect_, NHasAttr_, NAbs_, NLet_, NIf_, NWith_, NAssert_, NSynHole_ #-}+pattern NSynHoleAnnF     :: SrcSpan -> VarName -> NExprLocF r+pattern NSynHoleAnnF     ann x      = AnnF ann (NSynHole x)+{-# complete NConstantAnnF, NStrAnnF, NSymAnnF, NListAnnF, NSetAnnF, NLiteralPathAnnF, NEnvPathAnnF, NUnaryAnnF, NBinaryAnnF, NSelectAnnF, NHasAttrAnnF, NAbsAnnF, NLetAnnF, NIfAnnF, NWithAnnF, NAssertAnnF, NSynHoleAnnF #-}+++pattern NConstantAnn    :: SrcSpan -> NAtom -> NExprLoc+pattern NConstantAnn    ann x      = Ann ann (NConstant x)++pattern NStrAnn         :: SrcSpan -> NString NExprLoc -> NExprLoc+pattern NStrAnn         ann x      = Ann ann (NStr x)++pattern NSymAnn         :: SrcSpan -> VarName -> NExprLoc+pattern NSymAnn         ann x      = Ann ann (NSym x)++pattern NListAnn        :: SrcSpan -> [NExprLoc] -> NExprLoc+pattern NListAnn        ann x      = Ann ann (NList x)++pattern NSetAnn         :: SrcSpan -> Recursivity -> [Binding NExprLoc] -> NExprLoc+pattern NSetAnn         ann rec x  = Ann ann (NSet rec x)++pattern NLiteralPathAnn :: SrcSpan -> Path -> NExprLoc+pattern NLiteralPathAnn ann x      = Ann ann (NLiteralPath x)++pattern NEnvPathAnn     :: SrcSpan -> Path -> NExprLoc+pattern NEnvPathAnn     ann x      = Ann ann (NEnvPath x)++pattern NUnaryAnn       :: SrcSpan -> NUnaryOp -> NExprLoc -> NExprLoc+pattern NUnaryAnn       ann op x   = Ann ann (NUnary op x)++pattern NBinaryAnn      :: SrcSpan -> NBinaryOp -> NExprLoc -> NExprLoc -> NExprLoc+pattern NBinaryAnn      ann op x y = Ann ann (NBinary op x y)++pattern NSelectAnn      :: SrcSpan ->  Maybe NExprLoc -> NExprLoc -> NAttrPath NExprLoc -> NExprLoc+pattern NSelectAnn      ann v x p  = Ann ann (NSelect v x p)++pattern NHasAttrAnn     :: SrcSpan -> NExprLoc -> NAttrPath NExprLoc -> NExprLoc+pattern NHasAttrAnn     ann x p    = Ann ann (NHasAttr x p)++pattern NAbsAnn         :: SrcSpan -> Params NExprLoc -> NExprLoc -> NExprLoc+pattern NAbsAnn         ann x b    = Ann ann (NAbs x b)++pattern NLetAnn         :: SrcSpan -> [Binding NExprLoc] -> NExprLoc -> NExprLoc+pattern NLetAnn         ann x b    = Ann ann (NLet x b)++pattern NIfAnn          :: SrcSpan -> NExprLoc -> NExprLoc -> NExprLoc -> NExprLoc+pattern NIfAnn          ann c t e  = Ann ann (NIf c t e)++pattern NWithAnn        :: SrcSpan -> NExprLoc -> NExprLoc -> NExprLoc+pattern NWithAnn        ann x y    = Ann ann (NWith x y)++pattern NAssertAnn      :: SrcSpan -> NExprLoc -> NExprLoc -> NExprLoc+pattern NAssertAnn      ann x y    = Ann ann (NAssert x y)++pattern NSynHoleAnn     :: SrcSpan -> VarName -> NExprLoc+pattern NSynHoleAnn     ann x      = Ann ann (NSynHole x)+{-# complete NConstantAnn, NStrAnn, NSymAnn, NListAnn, NSetAnn, NLiteralPathAnn, NEnvPathAnn, NUnaryAnn, NBinaryAnn, NSelectAnn, NHasAttrAnn, NAbsAnn, NLetAnn, NIfAnn, NWithAnn, NAssertAnn, NSynHoleAnn #-}
src/Nix/Frames.hs view
@@ -1,6 +1,5 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# language ConstraintKinds #-}+{-# language ExistentialQuantification #-}  -- | Definitions of Frames. Frames are messages that gather and ship themself with a context related to the message. For example - the message about some exception would also gather, keep and bring with it the tracing information. module Nix.Frames@@ -12,30 +11,20 @@   , withFrame   , throwError   , module Data.Typeable-  , module Control.Exception   ) where -import           Prelude                 hiding ( traceM ) import           Data.Typeable           hiding ( typeOf ) import           Control.Monad.Catch            ( MonadThrow(..) )-import           Control.Exception       hiding ( catch-                                                , evaluate-                                                ) import qualified Text.Show-import           Nix.Utils                      ( Has(..)-                                                , view-                                                , over-                                                , traceM-                                                )  data NixLevel = Fatal | Error | Warning | Info | Debug-    deriving (Ord, Eq, Bounded, Enum, Show)+  deriving (Ord, Eq, Bounded, Enum, Show)  data NixFrame = NixFrame-    { frameLevel :: NixLevel-    , frame      :: SomeException-    }+  { frameLevel :: NixLevel+  , frame      :: SomeException+  }  instance Show NixFrame where   show (NixFrame level f) =@@ -46,7 +35,7 @@ type Framed e m = (MonadReader e m, Has e Frames, MonadThrow m)  newtype NixException = NixException Frames-    deriving Show+  deriving Show  instance Exception NixException 
src/Nix/Fresh.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}+{-# language CPP #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language TypeFamilies #-}+{-# language UndecidableInstances #-} -{-# OPTIONS_GHC -Wno-orphans #-}+{-# options_ghc -Wno-orphans #-}   module Nix.Fresh where@@ -21,7 +21,7 @@ import           Nix.Thunk  --  2021-06-02: NOTE: Remove singleton newtype accessor in favour of free coerce-newtype FreshIdT i m a = FreshIdT { unFreshIdT :: ReaderT (Ref m i) m a }+newtype FreshIdT i m a = FreshIdT (ReaderT (Ref m i) m a)   deriving     ( Functor     , Applicative@@ -60,4 +60,4 @@     atomicModifyRef v (\i -> (succ i, i))  runFreshIdT :: Functor m => Ref m i -> FreshIdT i m a -> m a-runFreshIdT i m = runReaderT (unFreshIdT m) i+runFreshIdT i m = runReaderT (coerce m) i
src/Nix/Fresh/Basic.hs view
@@ -1,7 +1,6 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# language CPP #-} -{-# OPTIONS_GHC -Wno-orphans #-}+{-# options_ghc -Wno-orphans #-}   module Nix.Fresh.Basic where@@ -29,7 +28,7 @@  instance (MonadEffects t f m, MonadDataContext f m)   => MonadEffects t f (StdIdT m) where-  makeAbsolutePath = lift . makeAbsolutePath @t @f @m+  toAbsolutePath = lift . toAbsolutePath @t @f @m   findEnvPath      = lift . findEnvPath @t @f @m   findPath vs path = do     i <- FreshIdT ask
src/Nix/Json.hs view
@@ -4,30 +4,44 @@  import qualified Data.Aeson                    as A import qualified Data.Aeson.Encoding           as A-import qualified Data.HashMap.Lazy             as HM-import qualified Data.Text.Lazy.Encoding       as TL+import qualified Data.Vector                   as V+import qualified Data.HashMap.Strict           as HM #if MIN_VERSION_aeson(2,0,0) import qualified Data.Aeson.Key                as AKM import qualified Data.Aeson.KeyMap             as AKM-#else-import           Nix.Expr.Types #endif-import qualified Data.Vector                   as V import           Nix.Atoms import           Nix.Effects import           Nix.Exec import           Nix.Frames import           Nix.String-import           Nix.Utils import           Nix.Value import           Nix.Value.Monad+import           Nix.Expr.Types +-- This was moved from Utils.+toEncodingSorted :: A.Value -> A.Encoding+toEncodingSorted = \case+  A.Object m ->+    A.pairs+      . fold+      . ((\(k, v) -> A.pair k $ toEncodingSorted v) <$>)+      . sortWith fst $+#if MIN_VERSION_aeson(2,0,0)+          AKM.toList+#else+          HM.toList+#endif+            m+  A.Array l -> A.list toEncodingSorted $ V.toList l+  v         -> A.toEncoding v+ nvalueToJSONNixString :: MonadNix e t f m => NValue t f m -> m NixString nvalueToJSONNixString =   runWithStringContextT .     fmap-      ( toStrict-      . TL.decodeUtf8+      ( decodeUtf8+      -- This is completely not optimal, but seems we do not have better encoding analog (except for @unsafe*@), Aeson gatekeeps through this.       . A.encodingToLazyByteString       . toEncodingSorted       )@@ -42,7 +56,7 @@   NVConstant NNull      -> pure   A.Null   NVStr      ns         -> A.toJSON <$> extractNixString ns   NVList l -> A.Array . V.fromList <$> traverse intoJson l-  NVSet m _ ->+  NVSet _ m ->     maybe       (A.Object <$> traverse intoJson kmap)       intoJson@@ -50,17 +64,18 @@    where #if MIN_VERSION_aeson(2,0,0)     lkup = AKM.lookup-    kmap = AKM.fromHashMap (HM.mapKeys (AKM.fromText . coerce) m)+    kmap = AKM.fromHashMap $ HM.mapKeys (AKM.fromText . coerce) m #else     lkup = HM.lookup     kmap = HM.mapKeys (coerce @VarName @Text) m #endif   NVPath p ->     do-      fp <- lift $ unStorePath <$> addPath p-      addSingletonStringContext $ StringContext (toText fp) DirectPath+      fp <- lift $ coerce <$> addPath p+      addSingletonStringContext $ StringContext (fromString fp) DirectPath       pure $ A.toJSON fp   v -> lift $ throwError $ CoercionToJson v   where+  intoJson :: MonadNix e t f m => NValue t f m -> WithStringContextT m A.Value   intoJson nv = join $ lift $ nvalueToJSON <$> demand nv
src/Nix/Lint.hs view
@@ -1,21 +1,19 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE UndecidableInstances #-}+{-# language ConstraintKinds #-}+{-# language CPP #-}+{-# language DataKinds #-}+{-# language GADTs #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language TypeFamilies #-}+{-# language UndecidableInstances #-} -{-# OPTIONS_GHC -fno-warn-name-shadowing #-}-{-# OPTIONS_GHC -Wno-missing-methods #-}+{-# options_ghc -fno-warn-name-shadowing #-}+{-# options_ghc -Wno-missing-methods #-}  module Nix.Lint where -import           Prelude                 hiding ( head-                                                , force-                                                )-import           Nix.Utils+import           Relude.Unsafe                 as Unsafe ( head )+import           Control.Exception              ( throw )+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import           Control.Monad                  ( foldM ) import           Control.Monad.Catch import           Control.Monad.Fix@@ -23,7 +21,7 @@ import           Control.Monad.ST import qualified Data.HashMap.Lazy             as M -- Plese, use NonEmpty-import           Data.List+import           Data.List                      ( intersect ) import qualified Data.List.NonEmpty            as NE import qualified Data.Text                     as Text import qualified Text.Show@@ -32,7 +30,8 @@ import           Nix.Convert import           Nix.Eval                       ( MonadEval(..) ) import qualified Nix.Eval                      as Eval-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Frames import           Nix.Fresh import           Nix.String@@ -53,7 +52,7 @@   = TConstant [TAtom]   | TStr   | TList r-  | TSet (Maybe (HashMap Text r))+  | TSet (Maybe (AttrSet r))   | TClosure (Params ())   | TPath   | TBuiltin Text (Symbolic m -> m r)@@ -103,7 +102,7 @@   :: MonadAtomicRef m   => [NTypeF m (Symbolic m)]   -> m (Symbolic m)-mkSymbolic xs = packSymbolic (NMany xs)+mkSymbolic = packSymbolic . NMany  packSymbolic   :: MonadAtomicRef m@@ -129,31 +128,50 @@ symerr = evalError @(Symbolic m) . ErrorCall . toString  renderSymbolic :: MonadLint e m => Symbolic m -> m Text-renderSymbolic = unpackSymbolic >=> \case-  NAny     -> pure "<any>"-  NMany xs -> fmap (Text.intercalate ", ") $ forM xs $ \case-    TConstant ys -> fmap (Text.intercalate ", ") $ forM ys $ pure . \case-      TInt   -> "int"-      TFloat -> "float"-      TBool  -> "bool"-      TNull  -> "null"-    TStr    -> pure "string"-    TList r -> do-      x <- renderSymbolic =<< demand r-      pure $ "[" <> x <> "]"-    TSet Nothing  -> pure "<any set>"-    TSet (Just s) -> do-      x <- traverse (renderSymbolic <=< demand) s-      pure $ "{" <> show x <> "}"-    f@(TClosure p) -> do-      (args, sym) <- do-        f' <- mkSymbolic [f]-        lintApp (NAbs (void p) ()) f' everyPossible-      args' <- traverse renderSymbolic args-      sym'  <- renderSymbolic sym-      pure $ "(" <> show args' <> " -> " <> sym' <> ")"-    TPath          -> pure "path"-    TBuiltin _n _f -> pure "<builtin function>"+renderSymbolic =+  (\case+    NAny     -> pure "<any>"+    NMany xs ->+      Text.intercalate ", " <$>+        traverse+          (\case+            TConstant ys ->+              pure $+                Text.intercalate ", "+                  (fmap+                    (\case+                      TInt   -> "int"+                      TFloat -> "float"+                      TBool  -> "bool"+                      TNull  -> "null"+                    )+                    ys+                  )+            TStr    -> pure "string"+            TList r ->+              fmap brackets $ renderSymbolic =<< demand r+            TSet Nothing  -> pure "<any set>"+            TSet (Just s) ->+              braces . show <$> traverse (renderSymbolic <=< demand) s+            f@(TClosure p) ->+              do+                (args, sym) <-+                  do+                    f' <- mkSymbolic $ one f+                    lintApp (NAbs p mempty) f' everyPossible+                args' <- traverse renderSymbolic args+                sym'  <- renderSymbolic sym+                pure $ parens $ show args' <> " -> " <> sym'+            TPath          -> pure "path"+            TBuiltin _n _f -> pure "<builtin function>"+          )+          xs+  ) <=< unpackSymbolic+ where+  between a b c = a <> b <> c+  parens = between "(" ")"+  brackets = between "[" "]"+  braces = between "{" "}"  -- This function is order and uniqueness preserving (of types). merge@@ -171,20 +189,19 @@     -> m [NTypeF m (Symbolic m)]   go []       _        = stub   go _        []       = stub-  go (x : xs) (y : ys) = case (x, y) of-    (TStr , TStr ) -> (TStr :) <$> go xs ys-    (TPath, TPath) -> (TPath :) <$> go xs ys+  go xxs@(x : xs) yys@(y : ys) = case (x, y) of+    (TStr , TStr ) -> (one TStr <>) <$> rest+    (TPath, TPath) -> (one TPath <>) <$> rest     (TConstant ls, TConstant rs) ->-      (TConstant (ls `intersect` rs) :) <$> go xs ys+      (one (TConstant (ls `intersect` rs)) <>) <$> rest     (TList l, TList r) ->-      (\l' ->-        (\r' -> do-          m <- defer $ unify context l' r'-          (TList m :) <$> go xs ys-        ) =<< demand r-      ) =<< demand l-    (TSet x       , TSet Nothing ) -> (TSet x :) <$> go xs ys-    (TSet Nothing , TSet x       ) -> (TSet x :) <$> go xs ys+      do+        l' <- demand l+        r' <- demand r+        m <- defer $ unify context l' r'+        (one (TList m) <>) <$> rest+    (TSet x       , TSet Nothing ) -> (one (TSet x) <>) <$> rest+    (TSet Nothing , TSet x       ) -> (one (TSet x) <>) <$> rest     (TSet (Just l), TSet (Just r)) -> do       m <- sequenceA $ M.intersectionWith         (\ i j ->@@ -199,23 +216,26 @@         id         ((TSet (pure m) :) <$>)         (not $ M.null m)-        (go xs ys)+        rest      (TClosure{}, TClosure{}) ->       throwError $ ErrorCall "Cannot unify functions"     (TBuiltin _ _, TBuiltin _ _) ->       throwError $ ErrorCall "Cannot unify builtin functions"-    _ | compareTypes x y == LT -> go xs (y : ys)-      | compareTypes x y == GT -> go (x : xs) ys+    _ | compareTypes x y == LT -> go xs yys+      | compareTypes x y == GT -> go xxs ys       | otherwise              -> error "impossible"+   where+    rest :: m [NTypeF m (Symbolic m)]+    rest = go xs ys  {-     mergeFunctions pl nl fl pr fr xs ys = do         m <- sequenceA $ M.intersectionWith             (\i j -> i >>= \i' -> j >>= \j' -> case (i', j') of-                    (Nothing, Nothing) -> pure $ pure Nothing-                    (_, Nothing) -> pure Nothing-                    (Nothing, _) -> pure Nothing+                    (Nothing, Nothing) -> stub+                    (_, Nothing) -> stub+                    (Nothing, _) -> stub                     (Just i'', Just j'') ->                         pure . pure <$> unify context i'' j'')             (pure <$> pl) (pure <$> pr)@@ -254,7 +274,7 @@           writeRef y   (NMany m)           packSymbolic (NMany m)         )-        (do+        (               -- x' <- renderSymbolic (Symbolic x)               -- y' <- renderSymbolic (Symbolic y)           throwError $ ErrorCall "Cannot unify "@@ -273,9 +293,9 @@  instance FromValue NixString m (Symbolic m) where -instance FromValue (AttrSet (Symbolic m), AttrSet SourcePos) m (Symbolic m) where+instance FromValue (AttrSet (Symbolic m), PositionSet) m (Symbolic m) where -instance ToValue (AttrSet (Symbolic m), AttrSet SourcePos) m (Symbolic m) where+instance ToValue (AttrSet (Symbolic m), PositionSet) m (Symbolic m) where  instance (MonadThunkId m, MonadAtomicRef m, MonadCatch m)   => MonadValue (Symbolic m) m where@@ -297,7 +317,7 @@   instance MonadLint e m => MonadEval (Symbolic m) m where-  freeVariable var = symerr $ "Undefined variable '" <> var <> "'"+  freeVariable var = symerr $ "Undefined variable '" <> coerce var <> "'"    attrMissing ks ms =     evalError @(Symbolic m) $ ErrorCall $ toString $@@ -306,30 +326,30 @@         (\ s ->  "Could not look up attribute " <> attr <> " in " <> show s)         ms    where-    attr = Text.intercalate "." (NE.toList ks)+    attr = Text.intercalate "." $ NE.toList $ coerce ks    evalCurPos = do-    f <- mkSymbolic [TPath]-    l <- mkSymbolic [TConstant [TInt]]-    c <- mkSymbolic [TConstant [TInt]]-    mkSymbolic [TSet (pure (M.fromList [("file", f), ("line", l), ("col", c)]))]+    f <- mkSymbolic $ one TPath+    l <- mkSymbolic $ one $ TConstant $ one TInt+    c <- mkSymbolic $ one $ TConstant $ one TInt+    mkSymbolic $ one $ TSet (pure (M.fromList [("file", f), ("line", l), ("col", c)])) -  evalConstant c = mkSymbolic [go c]+  evalConstant c = mkSymbolic $ one $ fun c    where-    go =+    fun =       \case         NURI   _ -> TStr-        NInt   _ -> TConstant [TInt]-        NFloat _ -> TConstant [TFloat]-        NBool  _ -> TConstant [TBool]-        NNull    -> TConstant [TNull]+        NInt   _ -> TConstant $ one TInt+        NFloat _ -> TConstant $ one TFloat+        NBool  _ -> TConstant $ one TBool+        NNull    -> TConstant $ one TNull -  evalString      = const $ mkSymbolic [TStr]-  evalLiteralPath = const $ mkSymbolic [TPath]-  evalEnvPath     = const $ mkSymbolic [TPath]+  evalString      = const $ mkSymbolic $ one TStr+  evalLiteralPath = const $ mkSymbolic $ one TPath+  evalEnvPath     = const $ mkSymbolic $ one TPath    evalUnary op arg =-    unify (void (NUnary op arg)) arg =<< mkSymbolic [TConstant [TInt, TBool]]+    unify (void (NUnary op arg)) arg =<< mkSymbolic (one (TConstant [TInt, TBool]))    evalBinary = lintBinaryOp @@ -343,7 +363,7 @@        pushWeakScope         (case s of-          NMany [TSet (Just s')] -> pure s'+          NMany [TSet (Just (coerce -> scope))] -> pure scope           NMany [TSet Nothing] -> error "NYI: with unknown"           _ -> throwError $ ErrorCall "scope must be a set in with statement"         )@@ -355,18 +375,18 @@       f' <- f       let e = NIf cond t' f' -      _ <- unify (void e) cond =<< mkSymbolic [TConstant [TBool]]+      _ <- unify (void e) cond =<< mkSymbolic (one $ TConstant $ one TBool)       unify (void e) t' f'    evalAssert cond body =     do       body' <- body       let e = NAssert cond body'-      _ <- unify (void e) cond =<< mkSymbolic [TConstant [TBool]]+      _ <- unify (void e) cond =<< mkSymbolic (one $ TConstant $ one TBool)       pure body'    evalApp = (fmap snd .) . lintApp (NBinary NApp () ())-  evalAbs params _ = mkSymbolic [TClosure (void params)]+  evalAbs params _ = mkSymbolic (one $ TClosure $ void params)    evalError = throwError @@ -389,36 +409,41 @@           NEq     -> [TConstant [TInt, TBool, TNull], TStr, TList y]           NNEq    -> [TConstant [TInt, TBool, TNull], TStr, TList y] -          NLt     -> [TConstant [TInt, TBool, TNull]]-          NLte    -> [TConstant [TInt, TBool, TNull]]-          NGt     -> [TConstant [TInt, TBool, TNull]]-          NGte    -> [TConstant [TInt, TBool, TNull]]+          NLt     -> one $ TConstant [TInt, TBool, TNull]+          NLte    -> one $ TConstant [TInt, TBool, TNull]+          NGt     -> one $ TConstant [TInt, TBool, TNull]+          NGte    -> one $ TConstant [TInt, TBool, TNull] -          NAnd    -> [TConstant [TBool]]-          NOr     -> [TConstant [TBool]]-          NImpl   -> [TConstant [TBool]]+          NAnd    -> one $ TConstant $ one TBool+          NOr     -> one $ TConstant $ one TBool+          NImpl   -> one $ TConstant $ one TBool            -- jww (2018-04-01): NYI: Allow Path + Str-          NPlus   -> [TConstant [TInt], TStr, TPath]-          NMinus  -> [TConstant [TInt]]-          NMult   -> [TConstant [TInt]]-          NDiv    -> [TConstant [TInt]]+          NPlus   -> [TConstant $ one TInt, TStr, TPath]+          NMinus  -> one $ TConstant $ one TInt+          NMult   -> one $ TConstant $ one TInt+          NDiv    -> one $ TConstant $ one TInt -          NUpdate -> [TSet mempty]+          NUpdate -> one $ TSet mempty -          NConcat -> [TList y]+          NConcat -> one $ TList y #if __GLASGOW_HASKELL__ < 900           _ -> fail "Should not be possible"  -- symerr or this fun signature should be changed to work in type scope #endif+++  where   check lsym rsym xs =     do-      let e = NBinary op lsym rsym+      let+        e = NBinary op lsym rsym+        unifyE = unify (void e)        m <- mkSymbolic xs-      _ <- unify (void e) lsym m-      _ <- unify (void e) rsym m-      unify (void e) lsym rsym+      _ <- unifyE lsym m+      _ <- unifyE rsym m+      unifyE lsym rsym  infixl 1 `lintApp` lintApp@@ -428,25 +453,29 @@   -> Symbolic m   -> m (Symbolic m)   -> m (HashMap VarName (Symbolic m), Symbolic m)-lintApp context fun arg = unpackSymbolic fun >>= \case-  NAny ->-    throwError $ ErrorCall "Cannot apply something not known to be a function"-  NMany xs -> do-    (args, ys) <- fmap unzip $ forM xs $ \case-      TClosure _params -> arg >>= unpackSymbolic >>= \case-        NAny -> do-          error "NYI"+lintApp context fun arg =+  (\case+    NAny ->+      throwError $ ErrorCall "Cannot apply something not known to be a function"+    NMany xs -> do+      (args, ys) <- fmap unzip $ forM xs $ \case+        TClosure _params ->+          (\case+            NAny -> do+              error "NYI" -        NMany [TSet (Just _)] -> do-          error "NYI"+            NMany [TSet (Just _)] -> do+              error "NYI" -        NMany _ -> throwError $ ErrorCall "NYI: lintApp NMany not set"-      TBuiltin _ _f -> throwError $ ErrorCall "NYI: lintApp builtin"-      TSet _m       -> throwError $ ErrorCall "NYI: lintApp Set"-      _x            -> throwError $ ErrorCall "Attempt to call non-function"+            NMany _ -> throwError $ ErrorCall "NYI: lintApp NMany not set"+          ) =<< unpackSymbolic =<< arg+        TBuiltin _ _f -> throwError $ ErrorCall "NYI: lintApp builtin"+        TSet _m       -> throwError $ ErrorCall "NYI: lintApp Set"+        _x            -> throwError $ ErrorCall "Attempt to call non-function" -    y <- everyPossible-    (head args, ) <$> foldM (unify context) y ys+      y <- everyPossible+      (Unsafe.head args, ) <$> foldM (unify context) y ys+  ) =<< unpackSymbolic fun  newtype Lint s a = Lint   { runLint :: ReaderT (Context (Lint s) (Symbolic (Lint s))) (FreshIdT Int (ST s)) a }@@ -462,10 +491,10 @@     )  instance MonadThrow (Lint s) where-  throwM e = Lint $ ReaderT $ \_ -> throw e+  throwM e = Lint $ ReaderT $ const (throw e)  instance MonadCatch (Lint s) where-  catch _m _h = Lint $ ReaderT $ \_ -> fail "Cannot catch in 'Lint s'"+  catch _m _h = Lint $ ReaderT $ const (fail "Cannot catch in 'Lint s'")  runLintM :: Options -> Lint s a -> ST s a runLintM opts action = do@@ -475,7 +504,7 @@ symbolicBaseEnv   :: Monad m   => m (Scopes m (Symbolic m))-symbolicBaseEnv = pure mempty+symbolicBaseEnv = stub  lint :: Options -> NExprLoc -> ST s (Symbolic (Lint s)) lint opts expr =
src/Nix/Normal.hs view
@@ -1,18 +1,15 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE RankNTypes #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language DataKinds #-}+{-# language GADTs #-}+{-# language TypeFamilies #-}+{-# language RankNTypes #-}  -- | Code for normalization (reduction into a normal form) of Nix expressions. -- Nix language allows recursion, so some expressions do not converge. -- And so do not converge into a normal form. module Nix.Normal where -import           Prelude            hiding ( force )-import           Nix.Utils import           Control.Monad.Free        ( Free(..) ) import           Data.Set                  ( member                                            , insert@@ -23,7 +20,7 @@ import           Nix.Value  newtype NormalLoop t f m = NormalLoop (NValue t f m)-    deriving Show+  deriving Show  instance MonadDataErrorContext t f m => Exception (NormalLoop t f m) @@ -158,10 +155,10 @@     (\_ t ->       Free $         NValue' $-          foldr-            (addProvenance1 @m @(NValue t f m))+          foldl'+            (flip $ addProvenance1 @m @(NValue t f m))             cyc-            (reverse $ citations @m @(NValue t f m) t)+            (citations @m @(NValue t f m) t)     )     Free  where
src/Nix/Options.hs view
@@ -1,40 +1,42 @@-{-# LANGUAGE StrictData #-}+{-# language StrictData #-}  -- | Definitions & defaults for the CLI options module Nix.Options where  import           Data.Time +--  2021-07-15: NOTE: What these are? They need to be documented.+-- Also need better names. Foe example, Maybes & lists names need to show their type in the name. data Options = Options     { verbose      :: Verbosity     , tracing      :: Bool     , thunks       :: Bool     , values       :: Bool     , showScopes   :: Bool-    , reduce       :: Maybe FilePath+    , reduce       :: Maybe Path     , reduceSets   :: Bool     , reduceLists  :: Bool     , parse        :: Bool     , parseOnly    :: Bool     , finder       :: Bool-    , findFile     :: Maybe FilePath+    , findFile     :: Maybe Path     , strict       :: Bool     , evaluate     :: Bool     , json         :: Bool     , xml          :: Bool     , attr         :: Maybe Text-    , include      :: [FilePath]+    , include      :: [Path]     , check        :: Bool-    , readFrom     :: Maybe FilePath+    , readFrom     :: Maybe Path     , cache        :: Bool     , repl         :: Bool     , ignoreErrors :: Bool     , expression   :: Maybe Text     , arg          :: [(Text, Text)]     , argstr       :: [(Text, Text)]-    , fromFile     :: Maybe FilePath+    , fromFile     :: Maybe Path     , currentTime  :: UTCTime-    , filePaths    :: [FilePath]+    , filePaths    :: [Path]     }     deriving Show 
src/Nix/Options/Parser.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell #-}+{-# language TemplateHaskell #-}  -- | Code that configures presentation parser for the CLI options module Nix.Options.Parser where@@ -212,7 +212,7 @@   debugVersionOpt :: Parser (a -> a)   debugVersionOpt =     infoOption-      ( concat+      ( fold           [ "Version: ", showVersion version           , "\nCommit: ", $(gitHash)           , "\n  date: ", $(gitCommitDate)@@ -227,4 +227,4 @@ nixOptionsInfo current =   info     (helper <*> versionOpt <*> nixOptions current)-    (fullDesc <> progDesc "" <> header "hnix")+    (fullDesc <> progDesc mempty <> header "hnix")
src/Nix/Parser.hs view
@@ -1,773 +1,920 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveAnyClass #-}--{-# OPTIONS_GHC -fno-warn-name-shadowing #-}---- | Main module for parsing Nix expressions.-module Nix.Parser-  ( parseNixFile-  , parseNixFileLoc-  , parseNixText-  , parseNixTextLoc-  , parseFromFileEx-  , Parser-  , parseFromText-  , Result-  , reservedNames-  , OperatorInfo(..)-  , NSpecialOp(..)-  , NAssoc(..)-  , NOperatorDef-  , getUnaryOperator-  , getBinaryOperator-  , getSpecialOperator-  , nixToplevelForm-  , nixExpr-  , nixSet-  , nixBinders-  , nixSelector-  , nixSym-  , nixPath-  , nixString-  , nixUri-  , nixSearchPath-  , nixFloat-  , nixInt-  , nixBool-  , nixNull-  , symbol-  , whiteSpace-  )-where--import           Prelude                 hiding ( some-                                                , many-                                                , readFile-                                                )-import           Data.Foldable                  ( foldr1 )--import           Control.Monad                  ( msum )-import           Control.Monad.Combinators.Expr ( makeExprParser-                                                , Operator( Postfix-                                                          , InfixN-                                                          , InfixR-                                                          , Prefix-                                                          , InfixL-                                                          )-                                                )-import           Data.Char                      ( isAlpha-                                                , isDigit-                                                , isSpace-                                                )-import           Data.Data                      ( Data(..) )-import           Data.Fix                       ( Fix(..) )-import qualified Data.HashSet                  as HashSet-import qualified Data.Map                      as Map-import           Data.Text                      ( cons )-import           Nix.Expr                hiding ( ($>) )-import           Nix.Expr.Strings               ( escapeCodes-                                                , stripIndent-                                                , mergePlain-                                                , removePlainEmpty-                                                )-import           Nix.Render                     ( MonadFile(readFile) )-import           Prettyprinter                  ( Doc-                                                , pretty-                                                )--- `parser-combinators` ships performance enhanced & MonadPlus-aware combinators.--- For example `smome` and `many` impoted here.-import           Text.Megaparsec         hiding ( State )-import           Text.Megaparsec.Char           ( space1-                                                , string-                                                , letterChar-                                                , char-                                                )-import qualified Text.Megaparsec.Char.Lexer    as Lexer---- | Different to @isAlphaNum@-isAlphanumeric :: Char -> Bool-isAlphanumeric x = isAlpha x || isDigit x-{-# inline isAlphanumeric #-}--infixl 3 <+>-(<+>) :: MonadPlus m => m a -> m a -> m a-(<+>) = mplus-------------------------------------------------------------------------------------nixExpr :: Parser NExprLoc-nixExpr =-  makeExprParser-    nixTerm $-      snd <<$>>-        nixOperators nixSelector--antiStart :: Parser Text-antiStart = symbol "${" <?> "${"--nixAntiquoted :: Parser a -> Parser (Antiquoted a NExprLoc)-nixAntiquoted p =-  Antiquoted <$>-    (antiStart *> nixToplevelForm <* symbol "}")-      <+> Plain <$>-        p-      <?> "anti-quotation"--selDot :: Parser ()-selDot = try (symbol "." *> notFollowedBy nixPath) <?> "."--nixSelect :: Parser NExprLoc -> Parser NExprLoc-nixSelect term =-  do-    res <--      liftA2 build-        term-        (optional $-          liftA2 (,)-            (selDot *> nixSelector)-            (optional $ reserved "or" *> nixTerm)-        )-    continues <- optional $ lookAhead selDot--    maybe-      id-      (const nixSelect)-      continues-      (pure res)- where-  build-    :: NExprLoc-    -> Maybe ( Ann SrcSpan (NAttrPath NExprLoc)-        , Maybe NExprLoc-        )-    -> NExprLoc-  build t mexpr =-    maybe-      id-      (\ expr t -> (uncurry $ nSelectLoc t) expr)-      mexpr-      t--nixSelector :: Parser (Ann SrcSpan (NAttrPath NExprLoc))-nixSelector =-  annotateLocation $-    do-      (x : xs) <- keyName `sepBy1` selDot-      pure $ x :| xs--nixTerm :: Parser NExprLoc-nixTerm = do-  c <- try $ lookAhead $ satisfy $ \x ->-    pathChar x || (`elem` ("({[</\"'^" :: String)) x-  case c of-    '('  -> nixSelect nixParens-    '{'  -> nixSelect nixSet-    '['  -> nixList-    '<'  -> nixSearchPath-    '/'  -> nixPath-    '"'  -> nixString-    '\'' -> nixString-    '^'  -> nixSynHole-    _ ->-      msum-        $  [ nixSelect nixSet | c == 'r' ]-        <> [ nixPath | pathChar c ]-        <> if isDigit c-             then [ nixFloat, nixInt ]-             else-               [ nixUri | isAlpha c ]-               <> [ nixBool | c == 't' || c == 'f' ]-               <> [ nixNull | c == 'n' ]-               <> [ nixSelect nixSym ]--nixToplevelForm :: Parser NExprLoc-nixToplevelForm = keywords <+> nixLambda <+> nixExpr- where-  keywords = nixLet <+> nixIf <+> nixAssert <+> nixWith--nixSym :: Parser NExprLoc-nixSym = annotateLocation1 $ mkSymF <$> identifier--nixSynHole :: Parser NExprLoc-nixSynHole = annotateLocation1 $ mkSynHoleF <$> (char '^' *> identifier)--nixInt :: Parser NExprLoc-nixInt = annotateLocation1 (mkIntF <$> integer <?> "integer")--nixFloat :: Parser NExprLoc-nixFloat =-  annotateLocation1 (try (mkFloatF . realToFrac <$> float) <?> "float")--nixBool :: Parser NExprLoc-nixBool =-  annotateLocation1 (bool "true" True <+> bool "false" False) <?> "bool"- where-  bool str b = mkBoolF b <$ reserved str--nixNull :: Parser NExprLoc-nixNull = annotateLocation1 (mkNullF <$ reserved "null" <?> "null")---- | 'nixTopLevelForm' returns an expression annotated with a source position,--- however this position doesn't include the parsed parentheses, so remove the--- "inner" location annotateion and annotate again, including the parentheses.-nixParens :: Parser NExprLoc-nixParens = annotateLocation1 (parens (stripAnn . unFix <$> nixToplevelForm) <?> "parens")--nixList :: Parser NExprLoc-nixList = annotateLocation1 (brackets (NList <$> many nixTerm) <?> "list")--pathChar :: Char -> Bool-pathChar x =-  isAlphanumeric x || (`elem` ("._-+~" :: String)) x--slash :: Parser Char-slash =-  try-    (  char '/'-    <* notFollowedBy (satisfy (\x -> x == '/' || x == '*' || isSpace x))-    )-    <?> "slash"---- | A path surrounded by angle brackets, indicating that it should be--- looked up in the NIX_PATH environment variable at evaluation.-nixSearchPath :: Parser NExprLoc-nixSearchPath =-  annotateLocation1-    (mkPathF True <$>-      try (char '<' *> many (satisfy pathChar <+> slash) <* symbol ">")-      <?> "spath"-    )--pathStr :: Parser FilePath-pathStr =-  lexeme $-    liftA2 (<>)-      (many $ satisfy pathChar)-      (concat <$>-        some-          (liftA2 (:)-            slash-            (some $ satisfy pathChar)-          )-      )--nixPath :: Parser NExprLoc-nixPath = annotateLocation1 (try (mkPathF False <$> pathStr) <?> "path")--nixLet :: Parser NExprLoc-nixLet = annotateLocation1-  (reserved "let" *> (letBody <+> letBinders) <?> "let block")- where-  letBinders =-    liftA2 NLet-      nixBinders-      (reserved "in" *> nixToplevelForm)-  -- Let expressions `let {..., body = ...}' are just desugared-  -- into `(rec {..., body = ...}).body'.-  letBody    = (\x -> NSelect x (StaticKey "body" :| mempty) Nothing) <$> aset-  aset       = annotateLocation1 $ NSet NRecursive <$> braces nixBinders--nixIf :: Parser NExprLoc-nixIf = annotateLocation1-  (liftA3 NIf-    (reserved "if"   *> nixExpr        )-    (reserved "then" *> nixToplevelForm)-    (reserved "else" *> nixToplevelForm)-  <?> "if"-  )--nixAssert :: Parser NExprLoc-nixAssert = annotateLocation1-  (liftA2 NAssert-    (reserved "assert" *> nixToplevelForm)-    (semi              *> nixToplevelForm)-  <?> "assert"-  )--nixWith :: Parser NExprLoc-nixWith = annotateLocation1-  (liftA2 NWith-    (reserved "with" *> nixToplevelForm)-    (semi            *> nixToplevelForm)-  <?> "with"-  )--nixLambda :: Parser NExprLoc-nixLambda =-  liftA2 nAbs-    (annotateLocation $ try argExpr)-    nixToplevelForm--nixString :: Parser NExprLoc-nixString = nStr <$> annotateLocation nixString'--nixUri :: Parser NExprLoc-nixUri = lexeme $ annotateLocation1 $ try $ do-  start    <- letterChar-  protocol <- many $-    satisfy $-      \ x ->-        isAlphanumeric x-        || (`elem` ("+-." :: String)) x-  _       <- string ":"-  address <--    some $-      satisfy $-        \ x ->-          isAlphanumeric x-          || (`elem` ("%/?:@&=+$,-_.!~*'" :: String)) x-  pure $ NStr $ DoubleQuoted-    [Plain $ toText $ start : protocol ++ ':' : address]--nixString' :: Parser (NString NExprLoc)-nixString' = lexeme (doubleQuoted <+> indented <?> "string")- where-  doubleQuoted :: Parser (NString NExprLoc)-  doubleQuoted =-    DoubleQuoted-    . removePlainEmpty-    . mergePlain <$>-      ( doubleQ-      *> many (stringChar doubleQ (void $ char '\\') doubleEscape)-      <* doubleQ-      )-      <?> "double quoted string"--  doubleQ      = void $ char '"'-  doubleEscape = Plain . one <$> (char '\\' *> escapeCode)--  indented :: Parser (NString NExprLoc)-  indented =-    stripIndent <$>-      (indentedQ-      *> many (stringChar indentedQ indentedQ indentedEscape)-      <* indentedQ-      )-      <?> "indented string"--  indentedQ      = void (string "''" <?> "\"''\"")-  indentedEscape =-    try $-      do-        indentedQ-        (Plain <$> ("''" <$ char '\'' <+> "$" <$ char '$')) <+>-          do-            _ <- char '\\'-            c <- escapeCode--            pure $-              bool-                EscapedNewline-                (Plain $ one c)-                (c /= '\n')--  stringChar end escStart esc =-    Antiquoted <$>-      (antiStart *> nixToplevelForm <* char '}')-        <+> Plain . one <$>-          char '$' <+> esc <+> Plain . toText <$>-            some plainChar-   where-    plainChar =-      notFollowedBy (end <+> void (char '$') <+> escStart) *> anySingle--  escapeCode =-    msum-      [ c <$ char e | (c, e) <- escapeCodes ]-    <+> anySingle---- | Gets all of the arguments for a function.-argExpr :: Parser (Params NExprLoc)-argExpr =-  msum-    [ atLeft-    , onlyname-    , atRight-    ]-  <* symbol ":"- where-  -- An argument not in curly braces. There's some potential ambiguity-  -- in the case of, for example `x:y`. Is it a lambda function `x: y`, or-  -- a URI `x:y`? Nix syntax says it's the latter. So we need to fail if-  -- there's a valid URI parse here.-  onlyname =-    msum-      [ nixUri *> unexpected (Label ('v' :| "alid uri"))-      , Param <$> identifier-      ]--  -- Parameters named by an identifier on the left (`args @ {x, y}`)-  atLeft =-    try $-      do-        name               <- identifier <* symbol "@"-        (params, variadic) <- params-        pure $ ParamSet params variadic $ pure name--  -- Parameters named by an identifier on the right, or none (`{x, y} @ args`)-  atRight =-    do-      (params, variadic) <- params-      name               <- optional $ symbol "@" *> identifier-      pure $ ParamSet params variadic name--  -- Return the parameters set.-  params = braces getParams--  -- Collects the parameters within curly braces. Returns the parameters and-  -- a boolean indicating if the parameters are variadic.-  getParams :: Parser ([(Text, Maybe NExprLoc)], Bool)-  getParams = go mempty-   where-    -- Attempt to parse `...`. If this succeeds, stop and return True.-    -- Otherwise, attempt to parse an argument, optionally with a-    -- default. If this fails, then return what has been accumulated-    -- so far.-    go acc = ((acc, True) <$ symbol "...") <+> getMore-     where-      getMore =-        -- Could be nothing, in which just return what we have so far.-        option (acc, False) $-          do-            -- Get an argument name and an optional default.-            pair <--              liftA2 (,)-                identifier-                (optional $ question *> nixToplevelForm)--            let args = acc <> [pair]--            -- Either return this, or attempt to get a comma and restart.-            option (args, False) $ comma *> go args--nixBinders :: Parser [Binding NExprLoc]-nixBinders = (inherit <+> namedVar) `endBy` semi where-  inherit =-    do-      -- We can't use 'reserved' here because it would consume the whitespace-      -- after the keyword, which is not exactly the semantics of C++ Nix.-      try $ string "inherit" *> lookAhead (void (satisfy reservedEnd))-      p <- getSourcePos-      x <- whiteSpace *> optional scope-      liftA2 (Inherit x)-        (many keyName)-        (pure p)-        <?> "inherited binding"-  namedVar =-    do-      p <- getSourcePos-      liftA3 NamedVar-        (annotated <$> nixSelector)-        (equals *> nixToplevelForm)-        (pure p)-        <?> "variable binding"-  scope = nixParens <?> "inherit scope"--keyName :: Parser (NKeyName NExprLoc)-keyName = dynamicKey <+> staticKey- where-  staticKey  = StaticKey <$> identifier-  dynamicKey = DynamicKey <$> nixAntiquoted nixString'--nixSet :: Parser NExprLoc-nixSet = annotateLocation1 ((isRec <*> braces nixBinders) <?> "set")- where-  isRec = (reserved "rec" $> NSet NRecursive <?> "recursive set") <+> pure (NSet NNonRecursive)--parseNixFile :: MonadFile m => FilePath -> m (Result NExpr)-parseNixFile =-  parseFromFileEx $ stripAnnotation <$> (whiteSpace *> nixToplevelForm <* eof)--parseNixFileLoc :: MonadFile m => FilePath -> m (Result NExprLoc)-parseNixFileLoc = parseFromFileEx (whiteSpace *> nixToplevelForm <* eof)--parseNixText :: Text -> Result NExpr-parseNixText =-  parseFromText $ stripAnnotation <$> (whiteSpace *> nixToplevelForm <* eof)--parseNixTextLoc :: Text -> Result NExprLoc-parseNixTextLoc = parseFromText (whiteSpace *> nixToplevelForm <* eof)--{- Parser.Library -}--skipLineComment' :: Tokens Text -> Parser ()-skipLineComment' prefix =-  string prefix *> void (takeWhileP (pure "character") (\x -> x /= '\n' && x /= '\r'))--whiteSpace :: Parser ()-whiteSpace = do-  put =<< getSourcePos-  Lexer.space space1 lineCmnt blockCmnt- where-  lineCmnt  = skipLineComment' "#"-  blockCmnt = Lexer.skipBlockComment "/*" "*/"--lexeme :: Parser a -> Parser a-lexeme p = p <* whiteSpace--symbol :: Text -> Parser Text-symbol = lexeme . string--reservedEnd :: Char -> Bool-reservedEnd x =-  isSpace x || (`elem` ("{([})];:.\"'," :: String)) x-{-# inline reservedEnd #-}--reserved :: Text -> Parser ()-reserved n =-  lexeme $ try $ string n *> lookAhead (void (satisfy reservedEnd) <|> eof)--identifier :: Parser Text-identifier = lexeme $ try $ do-  ident <--    liftA2 cons-      (satisfy (\x -> isAlpha x || x == '_'))-      (takeWhileP mempty identLetter)-  guard $ not $ ident `HashSet.member` reservedNames-  pure ident- where-  identLetter x = isAlphanumeric x || x == '_' || x == '\'' || x == '-'---- We restrict the type of 'parens' and 'brackets' here because if they were to--- take a @Parser NExprLoc@ argument they would parse additional text which--- wouldn't be captured in the source location annotation.------ Braces and angles in hnix don't enclose a single expression so this type--- restriction would not be useful.-parens :: Parser (NExprF f) -> Parser (NExprF f)-parens   = between (symbol "(") (symbol ")")-braces :: ParsecT Void Text (State SourcePos) a -> ParsecT Void Text (State SourcePos) a-braces   = between (symbol "{") (symbol "}")--- angles    = between (symbol "<") (symbol ">")-brackets :: Parser (NExprF f) -> Parser (NExprF f)-brackets = between (symbol "[") (symbol "]")-semi :: Parser Text-semi     = symbol ";"-comma :: Parser Text-comma    = symbol ","--- colon     = symbol ":"--- dot       = symbol "."-equals :: Parser Text-equals   = symbol "="-question :: Parser Text-question = symbol "?"--integer :: Parser Integer-integer = lexeme Lexer.decimal--float :: Parser Double-float = lexeme Lexer.float--reservedNames :: HashSet Text-reservedNames =-  HashSet.fromList-    ["let", "in", "if", "then", "else", "assert", "with", "rec", "inherit"]--type Parser = ParsecT Void Text (State SourcePos)--type Result a = Either (Doc Void) a--parseFromFileEx :: MonadFile m => Parser a -> FilePath -> m (Result a)-parseFromFileEx parser file =-  do-    input <- decodeUtf8 <$> readFile file--    pure $-      either-        (Left . pretty . errorBundlePretty)-        pure-        $ (`evalState` initialPos file) $ runParserT parser file input--parseFromText :: Parser a -> Text -> Result a-parseFromText parser input =-  let stub = "<string>" in-  either-    (Left . pretty . errorBundlePretty)-    pure-    $ (`evalState` initialPos stub) $ (`runParserT` stub) parser input--{- Parser.Operators -}--data NSpecialOp = NHasAttrOp | NSelectOp-  deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)--data NAssoc = NAssocNone | NAssocLeft | NAssocRight-  deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)--data NOperatorDef-  = NUnaryDef   Text NUnaryOp-  | NBinaryDef  Text NBinaryOp  NAssoc-  | NSpecialDef Text NSpecialOp NAssoc-  deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)--annotateLocation :: Parser a -> Parser (Ann SrcSpan a)-annotateLocation p =-  do-    begin <- getSourcePos-    res <- p-    end   <- get -- The state set before the last whitespace--    pure $ Ann (SrcSpan begin end) res--annotateLocation1 :: Parser (NExprF NExprLoc) -> Parser NExprLoc-annotateLocation1 = fmap annToAnnF . annotateLocation--manyUnaryOp :: MonadPlus f => f (a -> a) -> f (a -> a)-manyUnaryOp f = foldr1 (.) <$> some f--operator :: Text -> Parser Text-operator op =-  case op of-    "-" -> tuneLexer "-" '>'-    "/" -> tuneLexer "/" '/'-    "<" -> tuneLexer "<" '='-    ">" -> tuneLexer ">" '='-    n   -> symbol n- where-  tuneLexer opchar nonextchar =-    lexeme . try $ string opchar <* notFollowedBy (char nonextchar)--opWithLoc :: Text -> o -> (Ann SrcSpan o -> a) -> Parser a-opWithLoc name op f =-  do-    Ann ann _ <--      annotateLocation $-        {- dbg (toString name) $ -}-        operator name--    pure $ f $ Ann ann op--binaryN :: Text -> NBinaryOp -> (NOperatorDef, Operator (ParsecT Void Text (State SourcePos)) NExprLoc)-binaryN name op =-  (NBinaryDef name op NAssocNone, InfixN $ opWithLoc name op nBinary)-binaryL :: Text -> NBinaryOp -> (NOperatorDef, Operator (ParsecT Void Text (State SourcePos)) NExprLoc)-binaryL name op =-  (NBinaryDef name op NAssocLeft, InfixL $ opWithLoc name op nBinary)-binaryR :: Text -> NBinaryOp -> (NOperatorDef, Operator (ParsecT Void Text (State SourcePos)) NExprLoc)-binaryR name op =-  (NBinaryDef name op NAssocRight, InfixR $ opWithLoc name op nBinary)-prefix :: Text -> NUnaryOp -> (NOperatorDef, Operator (ParsecT Void Text (State SourcePos)) NExprLoc)-prefix name op =-  (NUnaryDef name op, Prefix $ manyUnaryOp $ opWithLoc name op nUnary)--- postfix name op = (NUnaryDef name op,---                    Postfix (opWithLoc name op nUnary))--nixOperators-  :: Parser (Ann SrcSpan (NAttrPath NExprLoc))-  -> [[(NOperatorDef, Operator Parser NExprLoc)]]-nixOperators selector =-  [ -- This is not parsed here, even though technically it's part of the-    -- expression table. The problem is that in some cases, such as list-    -- membership, it's also a term. And since terms are effectively the-    -- highest precedence entities parsed by the expression parser, it ends up-    -- working out that we parse them as a kind of "meta-term".--    -- {-  1 -} [ (NSpecialDef "." NSelectOp NAssocLeft,-    --             Postfix $ do-    --                    sel <- seldot *> selector-    --                    mor <- optional (reserved "or" *> term)-    --                    pure $ \x -> nSelectLoc x sel mor) ]--    {-  2 -}-    [ ( NBinaryDef " " NApp NAssocLeft-      ,-        -- Thanks to Brent Yorgey for showing me this trick!-        InfixL $ nApp <$ symbol ""-      )-    ]-  , {-  3 -}-    [ prefix  "-"  NNeg ]-  , {-  4 -}-    [ ( NSpecialDef "?" NHasAttrOp NAssocLeft-      , Postfix $ symbol "?" *> (flip nHasAttr <$> selector)-      )-    ]-  , {-  5 -}-    [ binaryR "++" NConcat ]-  , {-  6 -}-    [ binaryL "*"  NMult-    , binaryL "/"  NDiv-    ]-  , {-  7 -}-    [ binaryL "+"  NPlus-    , binaryL "-"  NMinus-    ]-  , {-  8 -}-    [ prefix  "!"  NNot ]-  , {-  9 -}-    [ binaryR "//" NUpdate ]-  , {- 10 -}-    [ binaryL "<"  NLt-    , binaryL ">"  NGt-    , binaryL "<=" NLte-    , binaryL ">=" NGte-    ]-  , {- 11 -}-    [ binaryN "==" NEq-    , binaryN "!=" NNEq-    ]-  , {- 12 -}-    [ binaryL "&&" NAnd ]-  , {- 13 -}-    [ binaryL "||" NOr ]-  , {- 14 -}-    [ binaryR "->" NImpl ]-  ]--data OperatorInfo = OperatorInfo-  { precedence    :: Int-  , associativity :: NAssoc-  , operatorName  :: Text-  } deriving (Eq, Ord, Generic, Typeable, Data, Show)--getUnaryOperator :: NUnaryOp -> OperatorInfo-getUnaryOperator = (m Map.!)- where-  m =-    Map.fromList $-      concat $-        zipWith-          buildEntry-          [1 ..]-          (nixOperators $ fail "unused")--  buildEntry i =-    concatMap $-      \case-        (NUnaryDef name op, _) -> [(op, OperatorInfo i NAssocNone name)]-        _                      -> mempty--getBinaryOperator :: NBinaryOp -> OperatorInfo-getBinaryOperator = (m Map.!)- where-  m =-    Map.fromList $-      concat $-        zipWith-          buildEntry-          [1 ..]-          (nixOperators $ fail "unused")--  buildEntry i =-    concatMap $-      \case-        (NBinaryDef name op assoc, _) -> [(op, OperatorInfo i assoc name)]-        _                             -> mempty--getSpecialOperator :: NSpecialOp -> OperatorInfo-getSpecialOperator NSelectOp = OperatorInfo 1 NAssocLeft "."-getSpecialOperator o         = m Map.! o- where-  m =-    Map.fromList $-      concat $-        zipWith-          buildEntry-          [1 ..]-          (nixOperators $ fail "unused")--  buildEntry i =-    concatMap $-      \case-        (NSpecialDef name op assoc, _) -> [(op, OperatorInfo i assoc name)]-        _                              -> mempty+{-# language CPP #-}+{-# language DeriveAnyClass #-}++{-# options_ghc -fno-warn-name-shadowing #-}++-- | Main module for parsing Nix expressions.+module Nix.Parser+  ( parseNixFile+  , parseNixFileLoc+  , parseNixText+  , parseNixTextLoc+  , parseFromFileEx+  , Parser+  , parseFromText+  , Result+  , reservedNames+  , OperatorInfo(..)+  , NSpecialOp(..)+  , NAssoc(..)+  , NOperatorDef+  , getUnaryOperator+  , getBinaryOperator+  , getSpecialOperator+  , nixExpr+  , nixExprAlgebra+  , nixSet+  , nixBinders+  , nixSelector+  , nixSym+  , nixPath+  , nixString+  , nixUri+  , nixSearchPath+  , nixFloat+  , nixInt+  , nixBool+  , nixNull+  , whiteSpace+  )+where++import           Prelude                 hiding ( (<|>)+                                                , some+                                                , many+                                                )+import           Data.Foldable                  ( foldr1 )++import           Control.Monad                  ( msum )+import           Control.Monad.Combinators.Expr ( makeExprParser+                                                , Operator( Postfix+                                                          , InfixN+                                                          , InfixR+                                                          , Prefix+                                                          , InfixL+                                                          )+                                                )+import           Data.Char                      ( isAlpha+                                                , isDigit+                                                , isSpace+                                                )+import           Data.Data                      ( Data(..) )+import           Data.Fix                       ( Fix(..) )+import qualified Data.HashSet                  as HashSet+import qualified Data.Map                      as Map+import qualified Data.Text                     as Text+import           Nix.Expr.Types+import           Nix.Expr.Shorthands     hiding ( ($>) )+import           Nix.Expr.Types.Annotated+import           Nix.Expr.Strings               ( escapeCodes+                                                , stripIndent+                                                , mergePlain+                                                , removeEmptyPlains+                                                )+import           Nix.Render                     ( MonadFile() )+import           Prettyprinter                  ( Doc+                                                , pretty+                                                )+-- `parser-combinators` ships performance enhanced & MonadPlus-aware combinators.+-- For example `some` and `many` impoted here.+import           Text.Megaparsec         hiding ( (<|>)+                                                , State+                                                )+import           Text.Megaparsec.Char           ( space1+                                                , letterChar+                                                , char+                                                )+import qualified Text.Megaparsec.Char.Lexer    as Lexer+++type Parser = ParsecT Void Text (State SourcePos)++-- * Utils++-- | Different to @isAlphaNum@+isAlphanumeric :: Char -> Bool+isAlphanumeric x = isAlpha x || isDigit x+{-# inline isAlphanumeric #-}++-- | @<|>@ with additional preservation of @MonadPlus@ constraint.+infixl 3 <|>+(<|>) :: MonadPlus m => m a -> m a -> m a+(<|>) = mplus++-- ** Annotated++annotateLocation1 :: Parser a -> Parser (AnnUnit SrcSpan a)+annotateLocation1 p =+  do+    begin <- getSourcePos+    res <- p+    end   <- get -- The state set before the last whitespace++    pure $ AnnUnit (SrcSpan begin end) res++annotateLocation :: Parser (NExprF NExprLoc) -> Parser NExprLoc+annotateLocation = (annUnitToAnn <$>) . annotateLocation1++annotateNamedLocation :: String -> Parser (NExprF NExprLoc) -> Parser NExprLoc+annotateNamedLocation name = annotateLocation . label name+++-- ** Grammar++reservedNames :: HashSet VarName+reservedNames =+  HashSet.fromList+    ["let", "in", "if", "then", "else", "assert", "with", "rec", "inherit"]++reservedEnd :: Char -> Bool+reservedEnd x =+  isSpace x || (`elem` ("{([})];:.\"'," :: String)) x+{-# inline reservedEnd #-}++reserved :: Text -> Parser ()+reserved n =+  lexeme $ try $ chunk n *> lookAhead (void (satisfy reservedEnd) <|> eof)++exprAfterP :: Parser a -> Parser NExprLoc+exprAfterP p = p *> nixExpr++exprAfterSymbol :: Char -> Parser NExprLoc+exprAfterSymbol p = exprAfterP $ symbol p++exprAfterReservedWord :: Text -> Parser NExprLoc+exprAfterReservedWord word = exprAfterP $ reserved word++-- | A literal copy of @megaparsec@ one but with addition of the @\r@ for Windows EOL case (@\r\n@).+-- Overall, parser should simply @\r\n -> \n@.+skipLineComment' :: Tokens Text -> Parser ()+skipLineComment' prefix =+  chunk prefix *> void (takeWhileP (pure "character") $ \x -> x /= '\n' && x /= '\r')++whiteSpace :: Parser ()+whiteSpace =+  do+    put =<< getSourcePos+    Lexer.space space1 lineCmnt blockCmnt+ where+  lineCmnt  = skipLineComment' "#"+  blockCmnt = Lexer.skipBlockComment "/*" "*/"++-- | Lexeme is a unit of the language.+-- Convention is that after lexeme an arbitrary amount of empty entities (space, comments, line breaks) are allowed.+-- This lexeme definition just skips over superflous @megaparsec: lexeme@ abstraction.+lexeme :: Parser a -> Parser a+lexeme p = p <* whiteSpace++symbol :: Char -> Parser Char+symbol = lexeme . char++symbols :: Text -> Parser Text+symbols = lexeme . chunk++-- We restrict the type of 'parens' and 'brackets' here because if they were to+-- take a @Parser NExprLoc@ argument they would parse additional text which+-- wouldn't be captured in the source location annotation.+--+-- Braces and angles in hnix don't enclose a single expression so this type+-- restriction would not be useful.+parens :: Parser (NExprF f) -> Parser (NExprF f)+parens   = on between symbol '(' ')'++braces :: Parser a -> Parser a+braces   = on between symbol '{' '}'++brackets :: Parser (NExprF f) -> Parser (NExprF f)+brackets = on between symbol '[' ']'++antiquotedIsHungryForTrailingSpaces :: Bool -> Parser (Antiquoted v NExprLoc)+antiquotedIsHungryForTrailingSpaces hungry = Antiquoted <$> (antiStart *> nixExpr <* antiEnd)+ where+  antiStart :: Parser Text+  antiStart = label "${" $ symbols "${"++  antiEnd :: Parser Char+  antiEnd = label "}" $+    bool+      id+      lexeme+      hungry+      (char '}')++antiquotedLexeme :: Parser (Antiquoted v NExprLoc)+antiquotedLexeme = antiquotedIsHungryForTrailingSpaces True++antiquoted :: Parser (Antiquoted v NExprLoc)+antiquoted = antiquotedIsHungryForTrailingSpaces False++---------------------------------------------------------------------------------++-- * Parser parts++-- ** Constrants++nixNull :: Parser NExprLoc+nixNull =+  annotateNamedLocation "null" $+    mkNullF <$ reserved "null"++nixBool :: Parser NExprLoc+nixBool =+  annotateNamedLocation "bool" $+    on (<|>) lmkBool (True, "true") (False, "false")+ where+  lmkBool (b, txt) = mkBoolF b <$ reserved txt++integer :: Parser Integer+integer = lexeme Lexer.decimal++nixInt :: Parser NExprLoc+nixInt =+  annotateNamedLocation "integer" $+    mkIntF <$> integer++float :: Parser Double+float = lexeme Lexer.float++nixFloat :: Parser NExprLoc+nixFloat =+  annotateNamedLocation "float" $+    try $+      mkFloatF . realToFrac <$> float++nixUri :: Parser NExprLoc+nixUri =+  lexeme $+    annotateLocation $+      try $+        do+          start    <- letterChar+          protocol <-+            takeWhileP mempty $+              \ x ->+                isAlphanumeric x+                || (`elem` ("+-." :: String)) x+          _       <- single ':'+          address <-+            takeWhile1P mempty $+                \ x ->+                  isAlphanumeric x+                  || (`elem` ("%/?:@&=+$,-_.!~*'" :: String)) x+          pure . NStr . DoubleQuoted . one . Plain $ start `Text.cons` protocol <> ":" <> address+++-- ** Strings++nixAntiquoted :: Parser a -> Parser (Antiquoted a NExprLoc)+nixAntiquoted p =+  label "anti-quotation" $+    antiquotedLexeme+    <|> Plain <$> p++nixString' :: Parser (NString NExprLoc)+nixString' = label "string" $ lexeme $ doubleQuoted <|> indented+ where+  doubleQuoted :: Parser (NString NExprLoc)+  doubleQuoted =+    label "double quoted string" $+      DoubleQuoted . removeEmptyPlains . mergePlain <$>+        inQuotationMarks (many $ stringChar quotationMark (void $ char '\\') doubleEscape)+   where+    inQuotationMarks :: Parser a -> Parser a+    inQuotationMarks expr = quotationMark *> expr <* quotationMark++    quotationMark :: Parser ()+    quotationMark = void $ char '"'++    doubleEscape :: Parser (Antiquoted Text r)+    doubleEscape = Plain . one <$> (char '\\' *> escapeCode)++  indented :: Parser (NString NExprLoc)+  indented =+    label "indented string" $+      stripIndent <$>+        inIndentedQuotation (many $ join stringChar indentedQuotationMark indentedEscape)+   where+    indentedEscape :: Parser (Antiquoted Text r)+    indentedEscape =+      try $+        do+          indentedQuotationMark+          (Plain <$> ("''" <$ char '\'' <|> "$" <$ char '$'))+            <|>+              do+                _ <- char '\\'+                c <- escapeCode++                pure $+                  bool+                    EscapedNewline+                    (Plain $ one c)+                    (c /= '\n')++    inIndentedQuotation :: Parser a -> Parser a+    inIndentedQuotation expr = indentedQuotationMark *> expr <* indentedQuotationMark++    indentedQuotationMark :: Parser ()+    indentedQuotationMark = label "\"''\"" . void $ chunk "''"++  stringChar+    :: Parser ()+    -> Parser ()+    -> Parser (Antiquoted Text NExprLoc)+    -> Parser (Antiquoted Text NExprLoc)+  stringChar end escStart esc =+    antiquoted+    <|> Plain . one <$> char '$'+    <|> esc+    <|> Plain . fromString <$> some plainChar+   where+    plainChar :: Parser Char+    plainChar =+      notFollowedBy (end <|> void (char '$') <|> escStart) *> anySingle++  escapeCode :: Parser Char+  escapeCode =+    msum+      [ c <$ char e | (c, e) <- escapeCodes ]+    <|> anySingle++nixString :: Parser NExprLoc+nixString = annNStr <$> annotateLocation1 nixString'+++-- ** Names (variables aka symbols)++identifier :: Parser VarName+identifier =+  lexeme $+    try $+      do+        (coerce -> iD) <-+          liftA2 Text.cons+            (satisfy (\x -> isAlpha x || x == '_'))+            (takeWhileP mempty identLetter)+        guard $ not $ iD `HashSet.member` reservedNames+        pure iD+ where+  identLetter x = isAlphanumeric x || x == '_' || x == '\'' || x == '-'++nixSym :: Parser NExprLoc+nixSym = annotateLocation $ mkSymF <$> coerce identifier+++-- ** ( ) parens++-- | 'nixExpr' returns an expression annotated with a source position,+-- however this position doesn't include the parsed parentheses, so remove the+-- "inner" location annotateion and annotate again, including the parentheses.+nixParens :: Parser NExprLoc+nixParens =+  annotateNamedLocation "parens" $+    parens $ stripAnnF . unFix <$> nixExpr+++-- ** [ ] list++nixList :: Parser NExprLoc+nixList =+  annotateNamedLocation "list" $+    brackets $ NList <$> many nixTerm+++-- ** { } set++nixBinders :: Parser [Binding NExprLoc]+nixBinders = (inherit <|> namedVar) `endBy` symbol ';' where+  inherit =+    do+      -- We can't use 'reserved' here because it would consume the whitespace+      -- after the keyword, which is not exactly the semantics of C++ Nix.+      try $ chunk "inherit" *> lookAhead (void $ satisfy reservedEnd)+      p <- getSourcePos+      x <- whiteSpace *> optional scope+      label "inherited binding" $+        liftA2 (Inherit x)+          (many identifier)+          (pure p)+  namedVar =+    do+      p <- getSourcePos+      label "variable binding" $+        liftA3 NamedVar+          (annotated <$> nixSelector)+          (exprAfterSymbol '=')+          (pure p)+  scope = label "inherit scope" nixParens++nixSet :: Parser NExprLoc+nixSet =+  annotateNamedLocation "set" $+    isRec <*> braces nixBinders+ where+  isRec =+    label "recursive set" (reserved "rec" $> NSet Recursive)+    <|> pure (NSet mempty)++-- ** /x/y/z literal Path++pathChar :: Char -> Bool+pathChar x =+  isAlphanumeric x || (`elem` ("._-+~" :: String)) x++slash :: Parser Char+slash =+  label "slash " $+    try $+      char '/' <* notFollowedBy (satisfy $ \x -> x == '/' || x == '*' || isSpace x)++pathStr :: Parser Path+pathStr =+  lexeme $ coerce . toString <$>+    liftA2 (<>)+      (takeWhileP mempty pathChar)+      (Text.concat <$>+        some+          (liftA2 Text.cons+            slash+            (takeWhile1P mempty pathChar)+          )+      )++nixPath :: Parser NExprLoc+nixPath =+  annotateNamedLocation "path" $+    try $ mkPathF False <$> coerce pathStr+++-- ** <<x>> environment path++-- | A path surrounded by angle brackets, indicating that it should be+-- looked up in the NIX_PATH environment variable at evaluation.+nixSearchPath :: Parser NExprLoc+nixSearchPath =+  annotateNamedLocation "spath" $+    mkPathF True <$> try (lexeme $ char '<' *> many (satisfy pathChar <|> slash) <* char '>')+++-- ** Operators++data NSpecialOp = NHasAttrOp | NSelectOp+  deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)++data NAssoc = NAssocNone | NAssocLeft | NAssocRight+  deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)++data NOperatorDef+  = NUnaryDef          NUnaryOp   Text+  | NBinaryDef  NAssoc NBinaryOp  Text+  | NSpecialDef NAssoc NSpecialOp Text+  deriving (Eq, Ord, Generic, Typeable, Data, Show, NFData)++manyUnaryOp :: MonadPlus f => f (a -> a) -> f (a -> a)+manyUnaryOp f = foldr1 (.) <$> some f++operator :: Text -> Parser Text+operator op =+  case op of+    c@"-" -> c `without` '>'+    c@"/" -> c `without` '/'+    c@"<" -> c `without` '='+    c@">" -> c `without` '='+    n   -> symbols n+ where+  without :: Text -> Char -> Parser Text+  without opChar noNextChar =+    lexeme . try $ chunk opChar <* notFollowedBy (char noNextChar)++opWithLoc :: (AnnUnit SrcSpan o -> a) -> o -> Text -> Parser a+opWithLoc f op name =+  do+    AnnUnit ann _ <-+      annotateLocation1 $+        operator name++    pure . f $ AnnUnit ann op++binary+  :: NAssoc+  -> (Parser (NExprLoc -> NExprLoc -> NExprLoc) -> b)+  -> NBinaryOp+  -> Text+  -> (NOperatorDef, b)+binary assoc fixity op name =+  (NBinaryDef assoc op name, fixity $ opWithLoc annNBinary op name)++binaryN, binaryL, binaryR :: NBinaryOp -> Text -> (NOperatorDef, Operator Parser NExprLoc)+binaryN =+  binary NAssocNone InfixN+binaryL =+  binary NAssocLeft InfixL+binaryR =+  binary NAssocRight InfixR++prefix :: NUnaryOp -> Text -> (NOperatorDef, Operator Parser NExprLoc)+prefix op name =+  (NUnaryDef op name, Prefix $ manyUnaryOp $ opWithLoc annNUnary op name)+-- postfix name op = (NUnaryDef name op,+--                    Postfix (opWithLoc name op annNUnary))++nixOperators+  :: Parser (AnnUnit SrcSpan (NAttrPath NExprLoc))+  -> [[ ( NOperatorDef+       , Operator Parser NExprLoc+       )+    ]]+nixOperators selector =+  [ -- This is not parsed here, even though technically it's part of the+    -- expression table. The problem is that in some cases, such as list+    -- membership, it's also a term. And since terms are effectively the+    -- highest precedence entities parsed by the expression parser, it ends up+    -- working out that we parse them as a kind of "meta-term".++    -- {-  1 -}+    -- [ ( NSpecialDef "." NSelectOp NAssocLeft+    --   , Postfix $+    --       do+    --         sel <- seldot *> selector+    --         mor <- optional (reserved "or" *> term)+    --         pure $ \x -> annNSelect x sel mor)+    -- ]++    {-  2 -}+    one+      ( NBinaryDef NAssocLeft NApp " "+      ,+        -- Thanks to Brent Yorgey for showing me this trick!+        InfixL $ annNApp <$ symbols mempty+      )+  , {-  3 -}+    one $ prefix  NNeg "-"+  , {-  4 -}+    one+      ( NSpecialDef NAssocLeft NHasAttrOp "?"+      , Postfix $ symbol '?' *> (flip annNHasAttr <$> selector)+      )+  , {-  5 -}+    one $ binaryR NConcat "++"+  , {-  6 -}+    [ binaryL NMult "*"+    , binaryL NDiv  "/"+    ]+  , {-  7 -}+    [ binaryL NPlus "+"+    , binaryL NMinus "-"+    ]+  , {-  8 -}+    one $ prefix  NNot "!"+  , {-  9 -}+    one $ binaryR NUpdate "//"+  , {- 10 -}+    [ binaryL NLt "<"+    , binaryL NGt ">"+    , binaryL NLte "<="+    , binaryL NGte ">="+    ]+  , {- 11 -}+    [ binaryN NEq "=="+    , binaryN NNEq "!="+    ]+  , {- 12 -}+    one $ binaryL NAnd "&&"+  , {- 13 -}+    one $ binaryL NOr "||"+  , {- 14 -}+    one $ binaryR NImpl "->"+  ]++--  2021-08-10: NOTE:+--  All this is a sidecar:+--  * This type+--  * detectPrecedence+--  * getUnaryOperation+--  * getBinaryOperation+--  * getSpecialOperation+--  can reduced in favour of adding precedence field into @NOperatorDef@.+-- details: https://github.com/haskell-nix/hnix/issues/982+data OperatorInfo = OperatorInfo+  { precedence    :: Int+  , associativity :: NAssoc+  , operatorName  :: Text+  } deriving (Eq, Ord, Generic, Typeable, Data, Show)++detectPrecedence+  :: Ord a+  => ( Int+    -> (NOperatorDef, Operator Parser NExprLoc)+    -> [(a, OperatorInfo)]+    )+  -> a+  -> OperatorInfo+detectPrecedence spec = (mapOfOpWithPrecedence Map.!)+ where+  mapOfOpWithPrecedence =+    Map.fromList $+      fold $+        zipWith+          (foldMap . spec)+          [1 ..]+          l+   where+    l :: [[(NOperatorDef, Operator Parser NExprLoc)]]+    l = nixOperators $ fail "unused"++getUnaryOperator :: NUnaryOp -> OperatorInfo+getUnaryOperator = detectPrecedence spec+ where+  spec :: Int -> (NOperatorDef, b) -> [(NUnaryOp, OperatorInfo)]+  spec i =+    \case+      (NUnaryDef op name, _) -> one (op, OperatorInfo i NAssocNone name)+      _                      -> mempty++getBinaryOperator :: NBinaryOp -> OperatorInfo+getBinaryOperator = detectPrecedence spec+ where+  spec :: Int -> (NOperatorDef, b) -> [(NBinaryOp, OperatorInfo)]+  spec i =+    \case+      (NBinaryDef assoc op name, _) -> one (op, OperatorInfo i assoc name)+      _                             -> mempty++getSpecialOperator :: NSpecialOp -> OperatorInfo+getSpecialOperator NSelectOp = OperatorInfo 1 NAssocLeft "."+getSpecialOperator o         = detectPrecedence spec o+ where+  spec :: Int -> (NOperatorDef, b) -> [(NSpecialOp, OperatorInfo)]+  spec i =+      \case+        (NSpecialDef assoc op name, _) -> one (op, OperatorInfo i assoc name)+        _                              -> mempty++-- ** x: y lambda function++-- | Gets all of the arguments for a function.+argExpr :: Parser (Params NExprLoc)+argExpr =+  msum+    [ atLeft+    , onlyname+    , atRight+    ]+  <* symbol ':'+ where+  -- An argument not in curly braces. There's some potential ambiguity+  -- in the case of, for example `x:y`. Is it a lambda function `x: y`, or+  -- a URI `x:y`? Nix syntax says it's the latter. So we need to fail if+  -- there's a valid URI parse here.+  onlyname =+    msum+      [ nixUri *> unexpected (Label $ fromList "valid uri" )+      , Param <$> identifier+      ]++  -- Parameters named by an identifier on the left (`args @ {x, y}`)+  atLeft =+    try $+      do+        name             <- identifier <* symbol '@'+        (pset, variadic) <- params+        pure $ ParamSet (pure name) variadic pset++  -- Parameters named by an identifier on the right, or none (`{x, y} @ args`)+  atRight =+    do+      (pset, variadic) <- params+      name             <- optional $ symbol '@' *> identifier+      pure $ ParamSet name variadic pset++  -- Return the parameters set.+  params = braces getParams++  -- Collects the parameters within curly braces. Returns the parameters and+  -- an flag indication if the parameters are variadic.+  getParams = go mempty+   where+    -- Attempt to parse `...`. If this succeeds, stop and return True.+    -- Otherwise, attempt to parse an argument, optionally with a+    -- default. If this fails, then return what has been accumulated+    -- so far.+    go acc = ((acc, Variadic) <$ symbols "...") <|> getMore+     where+      getMore :: Parser ([(VarName, Maybe NExprLoc)], Variadic)+      getMore =+        -- Could be nothing, in which just return what we have so far.+        option (acc, mempty) $+          do+            -- Get an argument name and an optional default.+            pair <-+              liftA2 (,)+                identifier+                (optional $ exprAfterSymbol '?')++            let args = acc <> one pair++            -- Either return this, or attempt to get a comma and restart.+            option (args, mempty) $ symbol ',' *> go args++nixLambda :: Parser NExprLoc+nixLambda =+  liftA2 annNAbs+    (annotateLocation1 $ try argExpr)+    nixExpr+++-- ** let expression++nixLet :: Parser NExprLoc+nixLet =+  annotateNamedLocation "let block" $+    reserved "let" *> (letBody <|> letBinders)+ where+  letBinders =+    liftA2 NLet+      nixBinders+      (exprAfterReservedWord "in")+  -- Let expressions `let {..., body = ...}' are just desugared+  -- into `(rec {..., body = ...}).body'.+  letBody    = (\x -> NSelect Nothing x (one $ StaticKey "body")) <$> aset+  aset       = annotateLocation $ NSet Recursive <$> braces nixBinders++-- ** if then else++nixIf :: Parser NExprLoc+nixIf =+  annotateNamedLocation "if" $+    liftA3 NIf+      (reserved "if"   *> nixExprAlgebra)+      (exprAfterReservedWord "then")+      (exprAfterReservedWord "else")++-- ** with++nixWith :: Parser NExprLoc+nixWith =+  annotateNamedLocation "with" $+    liftA2 NWith+      (exprAfterReservedWord "with")+      (exprAfterSymbol       ';'   )+++-- ** assert++nixAssert :: Parser NExprLoc+nixAssert =+  annotateNamedLocation "assert" $+    liftA2 NAssert+      (exprAfterReservedWord "assert")+      (exprAfterSymbol       ';'     )++-- ** . - reference (selector) into attr++selDot :: Parser ()+selDot = label "." $ try (symbol '.' *> notFollowedBy nixPath)++keyName :: Parser (NKeyName NExprLoc)+keyName = dynamicKey <|> staticKey+ where+  staticKey  = StaticKey <$> identifier+  dynamicKey = DynamicKey <$> nixAntiquoted nixString'++nixSelector :: Parser (AnnUnit SrcSpan (NAttrPath NExprLoc))+nixSelector =+  annotateLocation1 $+    do+      (x : xs) <- keyName `sepBy1` selDot+      pure $ x :| xs++nixSelect :: Parser NExprLoc -> Parser NExprLoc+nixSelect term =+  do+    res <-+      liftA2 build+        term+        (optional $+          liftA2 (,)+            (selDot *> nixSelector)+            (optional $ reserved "or" *> nixTerm)+        )+    continues <- optional $ lookAhead selDot++    maybe+      id+      (const nixSelect)+      continues+      (pure res)+ where+  build+    :: NExprLoc+    -> Maybe+      ( AnnUnit SrcSpan (NAttrPath NExprLoc)+      , Maybe NExprLoc+      )+    -> NExprLoc+  build t =+    maybe+      t+      (\ (a, m) -> (`annNSelect` t) m a)+++-- ** _ - syntax hole++nixSynHole :: Parser NExprLoc+nixSynHole = annotateLocation $ mkSynHoleF <$> coerce (char '^' *> identifier)+++-- ** Expr & its constituents (Language term, expr algebra)++nixTerm :: Parser NExprLoc+nixTerm =+  do+    c <- try . lookAhead . satisfy $+      \x -> (`elem` ("({[</\"'^" :: String)) x || pathChar x+    case c of+      '('  -> nixSelect nixParens+      '{'  -> nixSelect nixSet+      '['  -> nixList+      '<'  -> nixSearchPath+      '/'  -> nixPath+      '"'  -> nixString+      '\'' -> nixString+      '^'  -> nixSynHole+      _ ->+        msum+          $  [ nixSelect nixSet | c == 'r' ]+          <> [ nixPath | pathChar c ]+          <> if isDigit c+              then [ nixFloat, nixInt ]+              else+                [ nixUri | isAlpha c ]+                <> [ nixBool | c == 't' || c == 'f' ]+                <> [ nixNull | c == 'n' ]+                <> one (nixSelect nixSym)++-- | Nix expression algebra parser.+-- "Expression algebra" is to explain @megaparsec@ use of the term "Expression" (parser for language algebraic coperators without any statements (without @let@ etc.)), which is essentially an algebra inside the language.+nixExprAlgebra :: Parser NExprLoc+nixExprAlgebra =+  makeExprParser+    nixTerm+    (snd <<$>>+      nixOperators nixSelector+    )++nixExpr :: Parser NExprLoc+nixExpr = keywords <|> nixLambda <|> nixExprAlgebra+ where+  keywords = nixLet <|> nixIf <|> nixAssert <|> nixWith+++-- * Parse++type Result a = Either (Doc Void) a++parseFromFileEx :: MonadFile m => Parser a -> Path -> m (Result a)+parseFromFileEx parser file =+  do+    input <- liftIO $ readFile file++    pure $+      either+        (Left . pretty . errorBundlePretty)+        pure+        $ (`evalState` initialPos (coerce file)) $ runParserT parser (coerce file) input++parseFromText :: Parser a -> Text -> Result a+parseFromText parser input =+  let stub = "<string>" in+  either+    (Left . pretty . errorBundlePretty)+    pure+    $ (`evalState` initialPos stub) $ (`runParserT` stub) parser input++fullContent :: Parser NExprLoc+fullContent = whiteSpace *> nixExpr <* eof++parseNixFile' :: MonadFile m => (Parser NExprLoc -> Parser a) -> Path -> m (Result a)+parseNixFile' f =+  parseFromFileEx $ f fullContent++parseNixFile :: MonadFile m => Path -> m (Result NExpr)+parseNixFile =+  parseNixFile' (stripAnnotation <$>)++parseNixFileLoc :: MonadFile m => Path -> m (Result NExprLoc)+parseNixFileLoc =+  parseNixFile' id++parseNixText' :: (Parser NExprLoc -> Parser a) -> Text -> Result a+parseNixText' f =+  parseFromText $ f fullContent++parseNixText :: Text -> Result NExpr+parseNixText =+  parseNixText' (stripAnnotation <$>)++parseNixTextLoc :: Text -> Result NExprLoc+parseNixTextLoc =+  parseNixText' id+
src/Nix/Pretty.hs view
@@ -1,14 +1,12 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ViewPatterns #-}+{-# language CPP #-}+{-# language AllowAmbiguousTypes #-} -{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# options_ghc -fno-warn-name-shadowing #-}   module Nix.Pretty where  import           Prelude                  hiding ( toList, group )-import           Nix.Utils import           Control.Monad.Free             ( Free(Free) ) import           Data.Fix                       ( Fix(..)                                                 , foldFix )@@ -23,7 +21,8 @@ import           Prettyprinter           hiding ( list ) import           Nix.Atoms import           Nix.Cited-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Expr.Strings import           Nix.Normal import           Nix.Parser@@ -101,80 +100,90 @@     (wasPath sub)  prettyString :: NString (NixDoc ann) -> Doc ann-prettyString (DoubleQuoted parts) = "\"" <> (mconcat . fmap prettyPart $ parts) <> "\""+prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\""  where   -- It serializes Text -> String, because the helper code is done for String,   -- please, can someone break that code.-  prettyPart (Plain t)      = pretty . concatMap escape . toString $ t+  prettyPart (Plain t)      = pretty . foldMap escape . toString $ t   prettyPart EscapedNewline = "''\\n"   prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}"   escape '"' = "\\\""   escape x   =     maybe-      [x]-      (('\\' :) . (: mempty))+      (one x)+      (('\\' :) . one)       (toEscapeCode x) prettyString (Indented _ parts) = group $ nest 2 $ vcat   ["''", content, "''"]  where   content = vsep . fmap prettyLine . stripLastIfEmpty . splitLines $ parts-  stripLastIfEmpty = reverse . f . reverse   where-    f ([Plain t] : xs) | Text.null (strip t) = xs-    f xs = xs+  stripLastIfEmpty :: [[Antiquoted Text r]] -> [[Antiquoted Text r]]+  stripLastIfEmpty = filter flt+   where+    flt :: [Antiquoted Text r] -> Bool+    flt [Plain t] | Text.null (strip t) = False+    flt _ = True+   prettyLine = hcat . fmap prettyPart   prettyPart (Plain t) =     pretty . replace "${" "''${" . replace "''" "'''" $ t   prettyPart EscapedNewline = "\\n"   prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}" +prettyVarName :: VarName -> Doc ann+prettyVarName = pretty @Text . coerce+ prettyParams :: Params (NixDoc ann) -> Doc ann-prettyParams (Param n           ) = pretty n-prettyParams (ParamSet s v mname) = prettyParamSet s v <>-  maybe-    mempty-    (\ name ->-       bool-         mempty-         ("@" <> pretty name)-         (not (Text.null name))-    )-    mname+prettyParams (Param n           ) = prettyVarName n+prettyParams (ParamSet mname variadic pset) =+  prettyParamSet variadic pset <>+     toDoc `whenJust` mname+ where+  toDoc :: VarName -> Doc ann+  toDoc (coerce -> name) =+    ("@" <> pretty name) `whenFalse` Text.null name -prettyParamSet :: ParamSet (NixDoc ann) -> Bool -> Doc ann-prettyParamSet args var =+prettyParamSet :: Variadic -> ParamSet (NixDoc ann) -> Doc ann+prettyParamSet variadic args =   encloseSep     "{ "     (align " }")     sep-    (fmap prettySetArg args <> prettyVariadic)+    (fmap prettySetArg args <> one "..." `whenTrue` (variadic == Variadic))  where   prettySetArg (n, maybeDef) =     maybe-      (pretty n)-      (\x -> pretty n <> " ? " <> withoutParens x)+      varName+      (\x -> varName <> " ? " <> withoutParens x)       maybeDef-  prettyVariadic = [ "..." | var ]+   where+    varName = prettyVarName n   sep            = align ", "  prettyBind :: Binding (NixDoc ann) -> Doc ann prettyBind (NamedVar n v _p) =   prettySelector n <> " = " <> withoutParens v <> ";" prettyBind (Inherit s ns _p) =-  "inherit " <> scope <> align (fillSep $ prettyKeyName <$> ns) <> ";"+  "inherit " <> scope <> align (fillSep $ prettyVarName <$> ns) <> ";"   where     scope =-      maybe-        mempty-        ((<> " ") . parens . withoutParens)-        s+      ((<> " ") . parens . withoutParens) `whenJust` s  prettyKeyName :: NKeyName (NixDoc ann) -> Doc ann-prettyKeyName (StaticKey "") = "\"\""-prettyKeyName (StaticKey key) | HashSet.member key reservedNames = "\"" <> pretty key <> "\""-prettyKeyName (StaticKey  key) = pretty key+prettyKeyName (StaticKey key) =+  bool+    "\"\""+    (bool+      varName+      ("\"" <> varName <> "\"")+      (HashSet.member key reservedNames)+    )+    (not $ Text.null $ coerce key)+ where+  varName = prettyVarName key prettyKeyName (DynamicKey key) =   runAntiquoted-    (DoubleQuoted [Plain "\n"])+    (DoubleQuoted $ one $ Plain "\n")     prettyString     (\ x -> "${" <> withoutParens x <> "}")     key@@ -183,7 +192,7 @@ prettySelector = hcat . punctuate "." . fmap prettyKeyName . NE.toList  prettyAtom :: NAtom -> NixDoc ann-prettyAtom atom = simpleExpr $ pretty $ atomText atom+prettyAtom = simpleExpr . pretty . atomText  prettyNix :: NExpr -> Doc ann prettyNix = withoutParens . foldFix exprFNixDoc@@ -195,16 +204,16 @@   -> Doc ann prettyOriginExpr = withoutParens . go  where-  go = exprFNixDoc . stripAnn . fmap render--  render :: Maybe (NValue t f m) -> NixDoc ann-  render Nothing = simpleExpr "_"-  render (Just (Free (reverse . citations @m -> p:_))) = go (_originExpr p)-  render _       = simpleExpr "?"-    -- render (Just (NValue (citations -> ps))) =-        -- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . withoutParens-        --                           . go . originExpr)-        --     mempty (reverse ps)+  go = exprFNixDoc . stripAnnF . fmap render+   where+    render :: Maybe (NValue t f m) -> NixDoc ann+    render Nothing = simpleExpr "_"+    render (Just (Free (reverse . citations @m -> p:_))) = go (_originExpr p)+    render _       = simpleExpr "?"+      -- render (Just (NValue (citations -> ps))) =+          -- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . withoutParens+          --                           . go . originExpr)+          --     mempty (reverse ps)  exprFNixDoc :: NExprF (NixDoc ann) -> NixDoc ann exprFNixDoc = \case@@ -212,9 +221,9 @@   NStr      str  -> simpleExpr $ prettyString str   NList xs ->     prettyContainer "[" (wrapParens appOpNonAssoc) "]" xs-  NSet NNonRecursive xs ->+  NSet NonRecursive xs ->     prettyContainer "{" prettyBind "}" xs-  NSet NRecursive xs ->+  NSet Recursive xs ->     prettyContainer "rec {" prettyBind "}" xs   NAbs args body ->     leastPrecedence $@@ -229,23 +238,26 @@     mkNixDoc       opInfo $       hsep-        [ wrapParens (f NAssocLeft) r1+        [ f NAssocLeft r1         , pretty $ operatorName opInfo-        , wrapParens (f NAssocRight) r2+        , f NAssocRight r2         ]    where     opInfo = getBinaryOperator op+    f :: NAssoc -> NixDoc ann1 -> Doc ann1     f x =-      bool-        opInfo-        (opInfo { associativity = NAssocNone })-        (associativity opInfo /= x)+      wrapParens+        $ bool+            opInfo+            (opInfo { associativity = NAssocNone })+            (associativity opInfo /= x)   NUnary op r1 ->     mkNixDoc-      opInfo-      (pretty (operatorName opInfo) <> wrapParens opInfo r1)-    where opInfo = getUnaryOperator op-  NSelect r' attr o ->+      opInfo $+      pretty (operatorName opInfo) <> wrapParens opInfo r1+   where+    opInfo = getUnaryOperator op+  NSelect o r' attr ->     maybe       (mkNixDoc selectOp)       (const leastPrecedence)@@ -254,16 +266,13 @@    where     r     = mkNixDoc selectOp (wrapParens appOpNonAssoc r')     ordoc =-      maybe-        mempty-        ((" or " <>) . wrapParens appOpNonAssoc)-        o+      ((" or " <>) . wrapParens appOpNonAssoc) `whenJust` o   NHasAttr r attr ->     mkNixDoc hasAttrOp (wrapParens hasAttrOp r <> " ? " <> prettySelector attr)-  NEnvPath     p -> simpleExpr $ pretty ("<" <> p <> ">")+  NEnvPath     p -> simpleExpr $ pretty @String $ "<" <> coerce p <> ">"   NLiteralPath p ->     pathExpr $-      pretty $+      pretty @FilePath $ coerce $         case p of           "./"  -> "./."           "../" -> "../."@@ -272,8 +281,8 @@             bool               ("./" <> _txt)               _txt-              (any (`isPrefixOf` _txt) ["/", "~/", "./", "../"])-  NSym name -> simpleExpr $ pretty name+              (any (`isPrefixOf` coerce _txt) ["/", "~/", "./", "../"])+  NSym name -> simpleExpr $ prettyVarName name   NLet binds body ->     leastPrecedence $       group $@@ -295,12 +304,12 @@     prettyAddScope "with " scope body   NAssert cond body ->     prettyAddScope "assert " cond body-  NSynHole name -> simpleExpr $ pretty ("^" <> name)+  NSynHole name -> simpleExpr $ pretty @Text ("^" <> coerce name)  where   prettyContainer h f t c =     list       (simpleExpr (h <> t))-      (const $ simpleExpr $ group $ nest 2 $ vsep $ [h] <> (f <$> c) <> [t])+      (const $ simpleExpr $ group $ nest 2 $ vsep $ one h <> (f <$> c) <> one t)       c    prettyAddScope h c b =@@ -316,15 +325,15 @@    phi :: NValue' t f m NExpr -> NExprF NExpr   phi (NVConstant' a     ) = NConstant a-  phi (NVStr'      ns    ) = NStr $ DoubleQuoted [Plain (stringIgnoreContext ns)]+  phi (NVStr'      ns    ) = NStr $ DoubleQuoted $ one $ Plain $ stringIgnoreContext ns   phi (NVList'     l     ) = NList l-  phi (NVSet'      s    p) = NSet NNonRecursive-    [ NamedVar (StaticKey k :| mempty) v (fromMaybe nullPos (M.lookup k p))+  phi (NVSet'      p    s) = NSet mempty+    [ NamedVar (one $ StaticKey k) v (fromMaybe nullPos $ (`M.lookup` p) k)     | (k, v) <- toList s     ]   phi (NVClosure'  _    _) = NSym "<closure>"   phi (NVPath'     p     ) = NLiteralPath p-  phi (NVBuiltin'  name _) = NSym $ "builtins." <> name+  phi (NVBuiltin'  name _) = NSym $ coerce ((mappend @Text) "builtins.") name  prettyNValue   :: forall t f m ann . MonadDataContext f m => NValue t f m -> Doc ann@@ -346,7 +355,7 @@       fillSep         [ prettyNVal         , indent 2 $-          "(" <> mconcat ("from: " : (prettyOriginExpr . _originExpr <$> ps)) <> ")"+          "(" <> fold (one "from: " <> (prettyOriginExpr . _originExpr <$> ps)) <> ")"         ]     )     (citations @m @(NValue t f m) v)@@ -370,34 +379,36 @@       fillSep         [ v'         , indent 2 $-          "(" <> mconcat ( "thunk from: " : (prettyOriginExpr . _originExpr <$> ps)) <> ")"+          "(" <> fold (one "thunk from: " <> (prettyOriginExpr . _originExpr <$> ps)) <> ")"         ]  -- | This function is used only by the testing code.-printNix :: forall t f m . MonadDataContext f m => NValue t f m -> String+printNix :: forall t f m . MonadDataContext f m => NValue t f m -> Text printNix = iterNValueByDiscardWith thk phi  where-  thk = toString thunkStubText+  thk = thunkStubText -  phi :: NValue' t f m String -> String-  phi (NVConstant' a ) = toString $ atomText a+  phi :: NValue' t f m Text -> Text+  phi (NVConstant' a ) = atomText a   phi (NVStr'      ns) = show $ stringIgnoreContext ns-  phi (NVList'     l ) = toString $ "[ " <> unwords (fmap toText l) <> " ]"-  phi (NVSet' s _) =+  phi (NVList'     l ) = "[ " <> unwords l <> " ]"+  phi (NVSet' _ s) =     "{ " <>-      concat-        [ check (toString k) <> " = " <> v <> "; "-        | (k, v) <- sort $ toList s+      fold+        [ check k <> " = " <> v <> "; "+        | (coerce -> k, v) <- sort $ toList s         ] <> "}"    where-    check :: [Char] -> [Char]+    check :: Text -> Text     check v =       fromMaybe         v-        (fmap (surround . show) (readMaybe v :: Maybe Int)-        <|> fmap (surround . show) (readMaybe v :: Maybe Float)-        )-      where surround s = "\"" <> s <> "\""+        (tryRead @Int <|> tryRead @Float)+     where+      surround s = "\"" <> s <> "\""++      tryRead :: forall a . (Read a, Show a) => Maybe Text+      tryRead = fmap (surround . show) (readMaybe (toString v) :: Maybe a)   phi NVClosure'{}        = "<<lambda>>"-  phi (NVPath' fp       ) = fp-  phi (NVBuiltin' name _) = toString $ "<<builtin " <> name <> ">>"+  phi (NVPath' fp       ) = fromString $ coerce fp+  phi (NVBuiltin' name _) = "<<builtin " <> coerce name <> ">>"
src/Nix/Reduce.hs view
@@ -1,13 +1,11 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE PartialTypeSignatures #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ViewPatterns #-}+{-# language CPP #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language PartialTypeSignatures #-}+{-# language TypeFamilies #-} -{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# options_ghc -fno-warn-name-shadowing #-}   -- | This module provides a "reducing" expression evaluator, which reduces@@ -42,7 +40,8 @@ import qualified Text.Show import           Nix.Atoms import           Nix.Effects.Basic              ( pathToDefaultNixFile )-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Frames import           Nix.Options                    ( Options                                                 , reduceSets@@ -50,18 +49,16 @@                                                 ) import           Nix.Parser import           Nix.Scope-import           Nix.Utils import           System.Directory-import           System.FilePath  newtype Reducer m a = Reducer     { runReducer ::         ReaderT-          ( Maybe FilePath+          ( Maybe Path           , Scopes (Reducer m) NExprLoc           )           ( StateT-              ( HashMap FilePath NExprLoc+              ( HashMap Path NExprLoc               , HashMap Text Text               )             m@@ -71,8 +68,8 @@   deriving     ( Functor, Applicative, Alternative     , Monad, MonadPlus, MonadFix, MonadIO, MonadFail-    , MonadReader (Maybe FilePath, Scopes (Reducer m) NExprLoc)-    , MonadState (HashMap FilePath NExprLoc, HashMap Text Text)+    , MonadReader (Maybe Path, Scopes (Reducer m) NExprLoc)+    , MonadState (HashMap Path NExprLoc, HashMap Text Text)     )  staticImport@@ -80,59 +77,62 @@    . ( MonadIO m      , Scoped NExprLoc m      , MonadFail m-     , MonadReader (Maybe FilePath, Scopes m NExprLoc) m-     , MonadState (HashMap FilePath NExprLoc, HashMap Text Text) m+     , MonadReader (Maybe Path, Scopes m NExprLoc) m+     , MonadState (HashMap Path NExprLoc, HashMap Text Text) m      )   => SrcSpan-  -> FilePath+  -> Path   -> m NExprLoc-staticImport pann path = do-  mfile <- asks fst-  path  <- liftIO $ pathToDefaultNixFile path-  path' <- liftIO $ pathToDefaultNixFile =<< canonicalizePath-    (maybe id ((</>) . takeDirectory) mfile path)+staticImport pann path =+  do+    mfile <- asks fst+    path'  <- liftIO $ pathToDefaultNixFile path+    path'' <- liftIO $ pathToDefaultNixFile =<< coerce canonicalizePath+      (maybe id ((</>) . takeDirectory) mfile path') -  imports <- gets fst-  maybe-    (go path')-    pure-    (HM.lookup path' imports)- where-  go path = do-    liftIO $ putStrLn $ "Importing file " <> path+    let+      importIt :: m NExprLoc+      importIt = do+        liftIO $ putStrLn $ "Importing file " <> coerce path'' -    eres <- liftIO $ parseNixFileLoc path-    either-      (\ err -> fail $ "Parse failed: " <> show err)-      (\ x -> do-        let-          pos  = SourcePos "Reduce.hs" (mkPos 1) (mkPos 1)-          span = SrcSpan pos pos-          cur  =-            NamedVar-              (StaticKey "__cur_file" :| mempty)-              (Fix (NLiteralPath_ pann path))-              pos-          x' = Fix $ NLet_ span [cur] x-        modify $ first $ HM.insert path x'-        local-          (const (pure path, mempty)) $-          do-            x'' <- foldFix reduce x'-            modify $ first $ HM.insert path x''-            pure x''-      )-      eres+        eres <- liftIO $ parseNixFileLoc path''+        either+          (\ err -> fail $ "Parse failed: " <> show err)+          (\ x -> do+            let+              pos  = join (SourcePos "Reduce.hs") $ mkPos 1+              span = join SrcSpan pos+              cur  =+                NamedVar+                  (one $ StaticKey "__cur_file")+                  (NLiteralPathAnn pann path'')+                  pos+              x' = NLetAnn span (one cur) x+            modify $ first $ HM.insert path'' x'+            local+              (const (pure path'', mempty)) $+              do+                x'' <- foldFix reduce x'+                modify $ first $ HM.insert path'' x''+                pure x''+          )+          eres +    imports <- gets fst+    maybe+      importIt+      pure+      (HM.lookup path'' imports)+ -- gatherNames :: NExprLoc -> HashSet VarName -- gatherNames = foldFix $ \case---     NSym_ _ var -> S.singleton var---     Compose (Ann _ x) -> fold x+--     NSymAnnF _ var -> S.singleton var+--     AnnF _ x -> fold x  reduceExpr-  :: (MonadIO m, MonadFail m) => Maybe FilePath -> NExprLoc -> m NExprLoc+  :: (MonadIO m, MonadFail m) => Maybe Path -> NExprLoc -> m NExprLoc reduceExpr mpath expr =-  (`evalStateT` (mempty, mempty))+  (`evalStateT` mempty)     . (`runReaderT` (mpath, mempty))     . runReducer     $ foldFix reduce expr@@ -142,26 +142,26 @@    . ( MonadIO m      , Scoped NExprLoc m      , MonadFail m-     , MonadReader (Maybe FilePath, Scopes m NExprLoc) m-     , MonadState (HashMap FilePath NExprLoc, HashMap Text Text) m+     , MonadReader (Maybe Path, Scopes m NExprLoc) m+     , MonadState (HashMap Path NExprLoc, HashMap Text Text) m      )   => NExprLocF (m NExprLoc)   -> m NExprLoc  -- | Reduce the variable to its value if defined. --   Leave it as it is otherwise.-reduce (NSym_ ann var) =-  fromMaybe (Fix (NSym_ ann var)) <$> lookupVar var+reduce (NSymAnnF ann var) =+  fromMaybe (NSymAnn ann var) <$> lookupVar var  -- | Reduce binary and integer negation.-reduce (NUnary_ uann op arg) =+reduce (NUnaryAnnF uann op arg) =   do     x <- arg-    pure $ Fix $+    pure $       case (op, x) of-        (NNeg, Fix (NConstant_ cann (NInt  n))) -> NConstant_ cann $ NInt $ negate n-        (NNot, Fix (NConstant_ cann (NBool b))) -> NConstant_ cann $ NBool $ not b-        _                                       -> NUnary_    uann op x+        (NNeg, NConstantAnn cann (NInt  n)) -> NConstantAnn cann $ NInt $ negate n+        (NNot, NConstantAnn cann (NBool b)) -> NConstantAnn cann $ NBool $ not b+        _                                   -> NUnaryAnn    uann op x  -- | Reduce function applications. --@@ -169,32 +169,32 @@ -- --     * Reduce a lambda function by adding its name to the local --       scope and recursively reducing its body.-reduce (NBinary_ bann NApp fun arg) = fun >>= \case-  f@(Fix (NSym_ _ "import")) ->+reduce (NBinaryAnnF bann NApp fun arg) = fun >>= \case+  f@(NSymAnn _ "import") ->     (\case-        -- Fix (NEnvPath_     pann origPath) -> staticImport pann origPath-      Fix (NLiteralPath_ pann origPath) -> staticImport pann origPath-      v -> pure $ Fix $ NBinary_ bann NApp f v+        -- NEnvPathAnn     pann origPath -> staticImport pann origPath+      NLiteralPathAnn pann origPath -> staticImport pann origPath+      v -> pure $ NBinaryAnn bann NApp f v     ) =<< arg -  Fix (NAbs_ _ (Param name) body) ->+  NAbsAnn _ (Param name) body ->     do       x <- arg       pushScope-        (HM.singleton name x)+        (coerce $ HM.singleton name x)         (foldFix reduce body) -  f -> Fix . NBinary_ bann NApp f <$> arg+  f -> NBinaryAnn bann NApp f <$> arg  -- | Reduce an integer addition to its result.-reduce (NBinary_ bann op larg rarg) =+reduce (NBinaryAnnF bann op larg rarg) =   do     lval <- larg     rval <- rarg-    pure $ Fix $+    pure $       case (op, lval, rval) of-        (NPlus, Fix (NConstant_ ann (NInt x)), Fix (NConstant_ _ (NInt y))) -> NConstant_ ann  $ NInt $ x + y-        _                                                                   -> NBinary_   bann op lval rval+        (NPlus, NConstantAnn ann (NInt x), NConstantAnn _ (NInt y)) -> NConstantAnn ann  $ NInt $ x + y+        _                                                           -> NBinaryAnn   bann op lval rval  -- | Reduce a select on a Set by substituting the set to the selected value. --@@ -203,13 +203,13 @@ --   1. The selected expr is indeed a set. --   2. The selection AttrPath is a list of StaticKeys. --   3. The selected AttrPath exists in the set.-reduce base@(NSelect_ _ _ attrs _)+reduce base@(NSelectAnnF _ _ _ attrs)   | sAttrPath $ NE.toList attrs = do-    (NSelect_ _ aset attrs _) <- sequence base+    (NSelectAnnF _ _ aset attrs) <- sequenceA base     inspectSet (unFix aset) attrs   | otherwise = sId  where-  sId = Fix <$> sequence base+  sId = reduceLayer base   -- The selection AttrPath is composed of StaticKeys.   sAttrPath (StaticKey _ : xs) = sAttrPath xs   sAttrPath []                 = True@@ -220,7 +220,7 @@     n@(NamedVar (a' :| _) _ _) | a' == a -> pure n     _ -> findBind xs attrs   -- Follow the attrpath recursively in sets.-  inspectSet (NSet_ _ NNonRecursive binds) attrs = case findBind binds attrs of+  inspectSet (NSetAnnF _ NonRecursive binds) attrs = case findBind binds attrs of     Just (NamedVar _ e _) -> case NE.uncons attrs of       (_, Just attrs) -> inspectSet (unFix e) attrs       _               -> pure e@@ -231,49 +231,52 @@  -- | Reduce a set by inlining its binds outside of the set --   if none of the binds inherit the super set.-reduce e@(NSet_ ann NNonRecursive binds) =-  do-    let-      usesInherit =-        any-          (\case-            Inherit{} -> True-            _         -> False-          )-          binds--    bool-      (Fix <$> sequence e)-      (clearScopes @NExprLoc $ Fix . NSet_ ann NNonRecursive <$> traverse sequence binds)+reduce e@(NSetAnnF ann r binds) =+  bool+    -- Encountering a 'rec set' construction eliminates any hope of inlining+    -- definitions.+    mExprLoc+    (bool+      (reduceLayer e)+      mExprLoc       usesInherit+    )+    (r == NonRecursive)+ where+  mExprLoc :: m NExprLoc+  mExprLoc =+    clearScopes @NExprLoc $ NSetAnn ann r <$> traverse sequenceA binds --- Encountering a 'rec set' construction eliminates any hope of inlining--- definitions.-reduce (NSet_ ann NRecursive binds) =-  clearScopes @NExprLoc $ Fix . NSet_ ann NRecursive <$> traverse sequence binds+  usesInherit =+    any+      (\case+        Inherit{} -> True+        _         -> False+      )+      binds  -- Encountering a 'with' construction eliminates any hope of inlining -- definitions.-reduce (NWith_ ann scope body) =-  clearScopes @NExprLoc $ Fix <$> liftA2 (NWith_ ann) scope body+reduce (NWithAnnF ann scope body) =+  clearScopes @NExprLoc $ liftA2 (NWithAnn ann) scope body  -- | Reduce a let binds section by pushing lambdas, --   constants and strings to the body scope.-reduce (NLet_ ann binds body) =+reduce (NLetAnnF ann binds body) =   do-    binds' <- traverse sequence binds+    binds' <- traverse sequenceA binds     body'  <--      (`pushScope` body) . HM.fromList . catMaybes =<<+      (`pushScope` body) . coerce . HM.fromList . catMaybes =<<         traverse           (\case             NamedVar (StaticKey name :| []) def _pos ->               let                 defcase =                   \case-                    d@(Fix NAbs_     {}) -> pure (name, d)-                    d@(Fix NConstant_{}) -> pure (name, d)-                    d@(Fix NStr_     {}) -> pure (name, d)-                    _                    -> Nothing+                    d@NAbsAnn     {} -> pure (name, d)+                    d@NConstantAnn{} -> pure (name, d)+                    d@NStrAnn     {} -> pure (name, d)+                    _                -> Nothing               in               defcase <$> def @@ -282,11 +285,11 @@           binds      -- let names = gatherNames body'-    -- binds' <- traverse sequence binds <&> \b -> flip filter b $ \case+    -- binds' <- traverse sequenceA binds <&> \b -> flip filter b $ \case     --     NamedVar (StaticKey name _ :| []) _ ->     --         name `S.member` names     --     _ -> True-    pure $ Fix $ NLet_ ann binds' body'+    pure $ NLetAnn ann binds' body'     -- where     --   go m [] = pure m     --   go m (x:xs) = case x of@@ -297,34 +300,37 @@  -- | Reduce an if to the relevant path if --   the condition is a boolean constant.-reduce e@(NIf_ _ b t f) =+reduce e@(NIfAnnF _ b t f) =   (\case-    Fix (NConstant_ _ (NBool b')) -> if b' then t else f-    _                             -> Fix <$> sequence e+    NConstantAnn _ (NBool b') -> bool f t b'+    _                         -> reduceLayer e   ) =<< b  -- | Reduce an assert atom to its encapsulated --   symbol if the assertion is a boolean constant.-reduce e@(NAssert_ _ b body) =+reduce e@(NAssertAnnF _ b body) =   (\case-    Fix (NConstant_ _ (NBool b')) | b' -> body-    _ -> Fix <$> sequence e+    NConstantAnn _ (NBool True) -> body+    _ -> reduceLayer e   ) =<< b -reduce (NAbs_ ann params body) = do-  params' <- sequence params+reduce (NAbsAnnF ann params body) = do+  params' <- sequenceA params   -- Make sure that variable definitions in scope do not override function   -- arguments.   let-    args =+    scope = coerce $       case params' of-        Param    name     -> HM.singleton name $ Fix $ NSym_ ann name-        ParamSet pset _ _ ->-          HM.fromList $ (\(k, _) -> (k, Fix $ NSym_ ann k)) <$> pset-  Fix . NAbs_ ann params' <$> pushScope args body+        Param    name     -> one (name, NSymAnn ann name)+        ParamSet _ _ pset ->+          HM.fromList $ (\(k, _) -> (k, NSymAnn ann k)) <$> pset+  NAbsAnn ann params' <$> pushScope scope body -reduce v = Fix <$> sequence v+reduce v = reduceLayer v +reduceLayer :: (Traversable f1, Applicative f2) => f1 (f2 (Fix f1)) -> f2 (Fix f1)+reduceLayer v = Fix <$> sequenceA v+ -- newtype FlaggedF f r = FlaggedF { flagged :: (IORef Bool, f r) } newtype FlaggedF f r = FlaggedF (IORef Bool, f r)   deriving (Functor, Foldable, Traversable)@@ -337,7 +343,7 @@ flagExprLoc :: (MonadIO n, Traversable f) => Fix f -> n (Flagged f) flagExprLoc = foldFixM $ \x -> do   flag <- liftIO $ newIORef False-  pure $ Fix $ FlaggedF (flag, x)+  pure $ coerce (flag, x)  -- stripFlags :: Functor f => Flagged f -> Fix f -- stripFlags = foldFix $ Fix . snd . flagged@@ -348,7 +354,7 @@     \(FlaggedF (b, Compose x)) ->       bool         Nothing-        (Fix . Compose <$> traverse prune x)+        (annUnitToAnn <$> traverse prune x)         <$> liftIO (readIORef b)  where   prune :: NExprF (Maybe NExprLoc) -> Maybe (NExprF NExprLoc)@@ -360,30 +366,30 @@      NList l -> pure $ NList $       bool-        (fromMaybe nNull <$>)+        (fromMaybe annNNull <$>)         catMaybes         (reduceLists opts)  -- Reduce list members that aren't used; breaks if elemAt is used         l     NSet recur binds -> pure $ NSet recur $       bool-        (fromMaybe nNull <<$>>)-        (mapMaybe sequence)+        (fromMaybe annNNull <<$>>)+        (mapMaybe sequenceA)         (reduceSets opts)  -- Reduce set members that aren't used; breaks if hasAttr is used         binds -    NLet binds (Just body@(AnnE _ x)) ->+    NLet binds (Just body@(Ann _ x)) ->       pure $         list           x           (`NLet` body)           (mapMaybe pruneBinding binds) -    NSelect (Just aset) attr alt ->-      pure $ NSelect aset (pruneKeyName <$> attr) $ join alt+    NSelect alt (Just aset) attr ->+      pure $ NSelect (join alt) aset $ pruneKeyName <$> attr      -- These are the only short-circuiting binary operators-    NBinary NAnd (Just (AnnE _ larg)) _ -> pure larg-    NBinary NOr  (Just (AnnE _ larg)) _ -> pure larg+    NBinary NAnd (Just (Ann _ larg)) _ -> pure larg+    NBinary NOr  (Just (Ann _ larg)) _ -> pure larg      -- If the function was never called, it means its argument was in a     -- thunk that was forced elsewhere.@@ -393,22 +399,22 @@     -- invalid is that we're trying to emit what will reproduce whatever     -- fail the user encountered, which means providing all aspects of     -- the evaluation path they ultimately followed.-    NBinary op Nothing (Just rarg) -> pure $ NBinary op nNull rarg-    NBinary op (Just larg) Nothing -> pure $ NBinary op larg nNull+    NBinary op Nothing (Just rarg) -> pure $ NBinary op annNNull rarg+    NBinary op (Just larg) Nothing -> pure $ NBinary op larg annNNull      -- If the scope of a with was never referenced, it's not needed-    NWith Nothing (Just (AnnE _ body)) -> pure body+    NWith Nothing (Just (Ann _ body)) -> pure body      NAssert Nothing _              -> fail "How can an assert be used, but its condition not?"-    NAssert _ (Just (AnnE _ body)) -> pure body-    NAssert (Just cond) _          -> pure $ NAssert cond nNull+    NAssert _ (Just (Ann _ body)) -> pure body+    NAssert (Just cond) _          -> pure $ NAssert cond annNNull      NIf Nothing _ _ -> fail "How can an if be used, but its condition not?" -    NIf _ Nothing (Just (AnnE _ f)) -> pure f-    NIf _ (Just (AnnE _ t)) Nothing -> pure t+    NIf _ Nothing (Just (Ann _ f)) -> pure f+    NIf _ (Just (Ann _ t)) Nothing -> pure t -    x                     -> sequence x+    x                     -> sequenceA x    pruneString :: NString (Maybe NExprLoc) -> NString NExprLoc   pruneString (DoubleQuoted xs) = DoubleQuoted $ mapMaybe pruneAntiquotedText xs@@ -436,28 +442,28 @@    pruneParams :: Params (Maybe NExprLoc) -> Params NExprLoc   pruneParams (Param n) = Param n-  pruneParams (ParamSet xs b n) =-    ParamSet (reduceOrPassMode <$> xs) b n+  pruneParams (ParamSet mname variadic pset) =+    ParamSet mname variadic (reduceOrPassMode <$> pset)    where     reduceOrPassMode =       second $         bool           fmap-          ((pure .) . maybe nNull)+          ((pure .) . maybe annNNull)           (reduceSets opts)  -- Reduce set members that aren't used; breaks if hasAttr is used-          (fromMaybe nNull)+          (fromMaybe annNNull)    pruneBinding :: Binding (Maybe NExprLoc) -> Maybe (Binding NExprLoc)   pruneBinding (NamedVar _                 Nothing  _  ) = Nothing   pruneBinding (NamedVar xs                (Just x) pos) = pure $ NamedVar (pruneKeyName <$> xs) x pos   pruneBinding (Inherit  _                 []       _  ) = Nothing   pruneBinding (Inherit  (join -> Nothing) _        _  ) = Nothing-  pruneBinding (Inherit  (join -> m)       xs       pos) = pure $ Inherit m (pruneKeyName <$> xs) pos+  pruneBinding (Inherit  (join -> m)       xs       pos) = pure $ Inherit m xs pos  reducingEvalExpr   :: (Framed e m, Has e Options, Exception r, MonadCatch m, MonadIO m)   => (NExprLocF (m a) -> m a)-  -> Maybe FilePath+  -> Maybe Path   -> NExprLoc   -> m (NExprLoc, Either r a) reducingEvalExpr eval mpath expr =@@ -467,7 +473,7 @@       pure <$> foldFix (addEvalFlags eval) expr'     opts :: Options <- asks $ view hasLens     expr''          <- pruneTree opts expr'-    pure (fromMaybe nNull expr'', eres)+    pure (fromMaybe annNNull expr'', eres)  where   addEvalFlags k (FlaggedF (b, x)) = liftIO (writeIORef b True) *> k x 
src/Nix/Render.hs view
@@ -1,103 +1,100 @@-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE MultiWayIf #-}+{-# language UndecidableInstances #-}+{-# language CPP #-}+{-# language ConstraintKinds #-}+{-# language DefaultSignatures #-}+{-# language GADTs #-}+{-# language TypeFamilies #-}+{-# language TypeOperators #-}+{-# language MultiWayIf #-}  module Nix.Render where -import           Prelude                 hiding ( readFile )--import qualified Data.ByteString               as BS import qualified Data.Set                      as Set import           Nix.Utils.Fix1                 ( Fix1T-                                                , MonadFix1T )+                                                , MonadFix1T+                                                ) import           Nix.Expr.Types.Annotated import           Prettyprinter import qualified System.Directory              as S-import qualified System.Posix.Files            as S+import qualified System.PosixCompat.Files      as S import           Text.Megaparsec.Error import           Text.Megaparsec.Pos+import qualified Data.Text                     as Text -class MonadFail m => MonadFile m where-    readFile :: FilePath -> m ByteString-    default readFile :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m ByteString-    readFile = lift . readFile-    listDirectory :: FilePath -> m [FilePath]-    default listDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m [FilePath]+class (MonadFail m, MonadIO m) => MonadFile m where+    readFile :: Path -> m Text+    default readFile :: (MonadTrans t, MonadIO m', MonadFile m', m ~ t m') => Path -> m Text+    readFile = liftIO . Prelude.readFile+    listDirectory :: Path -> m [Path]+    default listDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => Path -> m [Path]     listDirectory = lift . listDirectory-    getCurrentDirectory :: m FilePath-    default getCurrentDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => m FilePath+    getCurrentDirectory :: m Path+    default getCurrentDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => m Path     getCurrentDirectory = lift getCurrentDirectory-    canonicalizePath :: FilePath -> m FilePath-    default canonicalizePath :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m FilePath+    canonicalizePath :: Path -> m Path+    default canonicalizePath :: (MonadTrans t, MonadFile m', m ~ t m') => Path -> m Path     canonicalizePath = lift . canonicalizePath-    getHomeDirectory :: m FilePath-    default getHomeDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => m FilePath+    getHomeDirectory :: m Path+    default getHomeDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => m Path     getHomeDirectory = lift getHomeDirectory-    doesPathExist :: FilePath -> m Bool-    default doesPathExist :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool+    doesPathExist :: Path -> m Bool+    default doesPathExist :: (MonadTrans t, MonadFile m', m ~ t m') => Path -> m Bool     doesPathExist = lift . doesPathExist-    doesFileExist :: FilePath -> m Bool-    default doesFileExist :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool+    doesFileExist :: Path -> m Bool+    default doesFileExist :: (MonadTrans t, MonadFile m', m ~ t m') => Path -> m Bool     doesFileExist = lift . doesFileExist-    doesDirectoryExist :: FilePath -> m Bool-    default doesDirectoryExist :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool+    doesDirectoryExist :: Path -> m Bool+    default doesDirectoryExist :: (MonadTrans t, MonadFile m', m ~ t m') => Path -> m Bool     doesDirectoryExist = lift . doesDirectoryExist-    getSymbolicLinkStatus :: FilePath -> m S.FileStatus-    default getSymbolicLinkStatus :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m S.FileStatus+    getSymbolicLinkStatus :: Path -> m S.FileStatus+    default getSymbolicLinkStatus :: (MonadTrans t, MonadFile m', m ~ t m') => Path -> m S.FileStatus     getSymbolicLinkStatus = lift . getSymbolicLinkStatus  instance MonadFile IO where-  readFile              = BS.readFile-  listDirectory         = S.listDirectory-  getCurrentDirectory   = S.getCurrentDirectory-  canonicalizePath      = S.canonicalizePath-  getHomeDirectory      = S.getHomeDirectory-  doesPathExist         = S.doesPathExist-  doesFileExist         = S.doesFileExist-  doesDirectoryExist    = S.doesDirectoryExist-  getSymbolicLinkStatus = S.getSymbolicLinkStatus+  readFile              = Prelude.readFile+  listDirectory         = coerce S.listDirectory+  getCurrentDirectory   = coerce S.getCurrentDirectory+  canonicalizePath      = coerce S.canonicalizePath+  getHomeDirectory      = coerce S.getHomeDirectory+  doesPathExist         = coerce S.doesPathExist+  doesFileExist         = coerce S.doesFileExist+  doesDirectoryExist    = coerce S.doesDirectoryExist+  getSymbolicLinkStatus = coerce S.getSymbolicLinkStatus  -instance (MonadFix1T t m, MonadFail (Fix1T t m), MonadFile m) => MonadFile (Fix1T t m)+instance (MonadFix1T t m, MonadIO (Fix1T t m), MonadFail (Fix1T t m), MonadFile m) => MonadFile (Fix1T t m)  posAndMsg :: SourcePos -> Doc a -> ParseError s Void posAndMsg (SourcePos _ lineNo _) msg =   FancyError     (unPos lineNo)-    (Set.fromList [ErrorFail (show msg) :: ErrorFancy Void])+    (Set.fromList $ one (ErrorFail (show msg) :: ErrorFancy Void))  renderLocation :: MonadFile m => SrcSpan -> Doc a -> m (Doc a)-renderLocation (SrcSpan (SourcePos file begLine begCol) (SourcePos file' endLine endCol)) msg-  | file == file' && file == "<string>" && begLine == endLine-  = pure $ "In raw input string at position " <> pretty (unPos begCol)+renderLocation (SrcSpan (SourcePos (coerce -> file) begLine begCol) (SourcePos (coerce -> file') endLine endCol)) msg+  | file == file' && file == "<string>" && begLine == endLine =+    pure $ "In raw input string at position " <> pretty (unPos begCol) -  | file /= "<string>" && file == file'-  = do-    exist <- doesFileExist file-    if exist-      then do+  | file /= "<string>" && file == file' =+    bool+      (pure msg)+      (do         txt <- sourceContext file begLine begCol endLine endCol msg         pure $           vsep             [ "In file " <> errorContext file begLine begCol endLine endCol <> ":"             , txt             ]-      else pure msg+      )+      =<< doesFileExist file renderLocation (SrcSpan beg end) msg = fail $ "Don't know how to render range from " <> show beg <>" to " <> show end <>" for fail: " <> show msg -errorContext :: FilePath -> Pos -> Pos -> Pos -> Pos -> Doc a-errorContext path bl bc _el _ec =+errorContext :: Path -> Pos -> Pos -> Pos -> Pos -> Doc a+errorContext (coerce @Path @FilePath -> path) bl bc _el _ec =   pretty path <> ":" <> pretty (unPos bl) <> ":" <> pretty (unPos bc)  sourceContext-  :: MonadFile m => FilePath -> Pos -> Pos -> Pos -> Pos -> Doc a -> m (Doc a)+  :: MonadFile m => Path -> Pos -> Pos -> Pos -> Pos -> Doc a -> m (Doc a) sourceContext path (unPos -> begLine) (unPos -> _begCol) (unPos -> endLine) (unPos -> _endCol) msg   = do     let beg' = max 1 $ begLine - 3@@ -107,31 +104,35 @@       .   take (end' - beg')       .   drop (pred beg')       .   lines-      .   decodeUtf8-      <$> readFile path+      <$> Nix.Render.readFile path     let-      longest = length $ show @String (beg' + (length ls) - 1)+      longest = Text.length $ show $ beg' + length ls - 1+      pad :: Int -> Text       pad n =         let+          ns :: Text           ns = show n-          nsp = replicate (longest - length ns) ' ' <> ns+          nsp = Text.replicate (longest - Text.length ns) " " <> ns         in           if           | n == begLine && n == endLine -> "==> " <> nsp <> " |  "           | n >= begLine && n <= endLine -> "  > " <> nsp <> " |  "           | otherwise                    -> "    " <> nsp <> " |  "       composeLine n l =-        [pretty (pad n) <> l]-        ++ [ pretty-               $  replicate (length (pad n) - 3) ' '-               <> "|  "-               <> replicate (_begCol - 1) ' '-               <> replicate (_endCol - _begCol) '^'-           | begLine == endLine && n == endLine ]+        one (pretty (pad n) <> l)+        <> whenTrue+            (one $+              pretty $+                Text.replicate (Text.length (pad n) - 3) " "+                <> "|"+                <> Text.replicate (_begCol + 1) " "+                <> Text.replicate (_endCol - _begCol) "^"+            )+            (begLine == endLine && n == endLine)         -- XXX: Consider inserting the message here when it is small enough.         -- ATM some messages are so huge that they take prevalence over the source listing.         -- ++ [ indent (length $ pad n) msg | n == endLine ] -      ls' = concat $ zipWith composeLine [beg' ..] ls+      ls' = fold $ zipWith composeLine [beg' ..] ls -    pure $ vsep $ ls' ++ [ indent (length $ pad begLine) msg ]+    pure $ vsep $ ls' <> one (indent (Text.length $ pad begLine) msg)
src/Nix/Render/Frame.hs view
@@ -1,21 +1,21 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}+{-# language CPP #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language MultiWayIf #-}+{-# language GADTs #-}+{-# language TypeFamilies #-}   -- | Code for rendering/representation of the messages packaged with their context (Frames). module Nix.Render.Frame where  import           Prelude             hiding ( Comparison )-import           Nix.Utils+import           GHC.Exception              ( ErrorCall ) import           Data.Fix                   ( Fix(..) )-import           Nix.Eval+import           Nix.Eval            hiding ( addMetaInfo ) import           Nix.Exec-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Frames import           Nix.Normal import           Nix.Options@@ -39,37 +39,39 @@   => Frames   -> m (Doc ann) renderFrames []       = stub-renderFrames (x : xs) = do-  opts :: Options <- asks (view hasLens)-  frames          <- if-    | verbose opts <= ErrorsOnly -> renderFrame @v @t @f x-    | verbose opts <= Informational -> do-      f <- renderFrame @v @t @f x-      pure $ concatMap go (reverse xs) <> f-    | otherwise -> concat <$> traverse (renderFrame @v @t @f) (reverse (x : xs))-  pure $-    list-      mempty-      vsep-      frames+renderFrames xss@(x : xs) =+  do+    opts :: Options <- asks $ view hasLens+    let+      verbosity :: Verbosity+      verbosity = verbose opts+    renderedFrames <- if+        | verbosity <= ErrorsOnly -> render1 x+      --  2021-10-22: NOTE: List reverse is completely conterproductive. `reverse` of list famously neest to traverse the whole list to take the last element+        | verbosity <= Informational -> (foldMap renderPosition (reverse xs) <>) <$> render1 x+        | otherwise -> foldMapM render1 (reverse xss)+    pure $ list mempty vsep renderedFrames  where-  go :: NixFrame -> [Doc ann]-  go f =-    maybe-      mempty-      (\ pos -> ["While evaluating at " <> pretty (sourcePosPretty pos) <> colon])-      (framePos @v @m f)+  render1 :: NixFrame -> m [Doc ann1]+  render1 = renderFrame @v @t @f +  renderPosition :: NixFrame -> [Doc ann]+  renderPosition =+    whenJust+      (\ pos -> one ("While evaluating at " <> pretty (sourcePosPretty pos) <> colon))+      . framePos @v @m+ framePos   :: forall v (m :: Type -> Type)    . (Typeable m, Typeable v)   => NixFrame   -> Maybe SourcePos-framePos (NixFrame _ f)-  | Just (e :: EvalFrame m v) <- fromException f = case e of-    EvaluatingExpr _ (AnnE (SrcSpan beg _) _) -> pure beg+framePos (NixFrame _ f) =+  (\case+    EvaluatingExpr _ (Ann (SrcSpan beg _) _) -> pure beg     _ -> Nothing-  | otherwise = Nothing+  )+  =<< fromException @(EvalFrame m v) f  renderFrame   :: forall v t f e m ann@@ -87,55 +89,57 @@   | Just (e :: ValueFrame t f m  ) <- fromException f = renderValueFrame level  e   | Just (e :: NormalLoop t f m  ) <- fromException f = renderNormalLoop level  e   | Just (e :: ExecFrame  t f m  ) <- fromException f = renderExecFrame  level  e-  | Just (e :: ErrorCall         ) <- fromException f = pure [pretty (Text.show e)]-  | Just (e :: SynHoleInfo    m v) <- fromException f = pure [pretty (Text.show e)]+  | Just (e :: ErrorCall         ) <- fromException f = pure $ one $ pretty (Text.show e)+  | Just (e :: SynHoleInfo    m v) <- fromException f = pure $ one $ pretty (Text.show e)   | otherwise = fail $ "Unrecognized frame: " <> show f  wrapExpr :: NExprF r -> NExpr wrapExpr x = Fix (Fix (NSym "<?>") <$ x)  renderEvalFrame-  :: (MonadReader e m, Has e Options, MonadFile m)+  :: forall e m v ann+  . (MonadReader e m, Has e Options, MonadFile m)   => NixLevel   -> EvalFrame m v   -> m [Doc ann] renderEvalFrame level f =   do     opts :: Options <- asks (view hasLens)+    let+      addMetaInfo :: ([Doc ann] -> [Doc ann]) -> SrcSpan -> Doc ann -> m [Doc ann]+      addMetaInfo trans loc = fmap (trans . one) . renderLocation loc+     case f of-      EvaluatingExpr scope e@(AnnE ann _) ->-        do-          let-            scopeInfo =-              bool-                mempty-                [pretty $ Text.show scope]-                (showScopes opts)-          fmap-            (\x -> scopeInfo <> [x])-            $ renderLocation ann =<<-                renderExpr level "While evaluating" "Expression" e+      EvaluatingExpr scope e@(Ann loc _) ->+        addMetaInfo+          (scopeInfo <>)+          loc+          =<< renderExpr level "While evaluating" "Expression" e+         where+          scopeInfo :: [Doc ann]+          scopeInfo =+            one (pretty $ Text.show scope) `whenTrue` showScopes opts -      ForcingExpr _scope e@(AnnE ann _) | thunks opts ->-        fmap-          (: mempty)-          $ renderLocation ann =<<-              renderExpr level "While forcing thunk from" "Forcing thunk" e+      ForcingExpr _scope e@(Ann loc _) | thunks opts ->+        addMetaInfo+          id+          loc+          =<< renderExpr level "While forcing thunk from" "Forcing thunk" e -      Calling name ann ->-        fmap-          (: mempty)-          $ renderLocation ann $-              "While calling builtins." <> pretty name+      Calling name loc ->+        addMetaInfo+          id+          loc+          $ "While calling builtins." <> pretty name        SynHole synfo ->-        sequence $-          let e@(AnnE ann _) = _synHoleInfo_expr synfo in--          [ renderLocation ann =<<+        sequenceA+          [ renderLocation loc =<<               renderExpr level "While evaluating" "Syntactic Hole" e           , pure $ pretty $ Text.show $ _synHoleInfo_scope synfo           ]+         where+          e@(Ann loc _) = _synHoleInfo_expr synfo        ForcingExpr _ _ -> stub @@ -147,18 +151,28 @@   -> Text   -> NExprLoc   -> m (Doc ann)-renderExpr _level longLabel shortLabel e@(AnnE _ x) = do+renderExpr _level longLabel shortLabel e@(Ann _ x) = do   opts :: Options <- asks (view hasLens)-  let rendered-          | verbose opts >= DebugInfo =-              pretty (PS.ppShow (stripAnnotation e))-          | verbose opts >= Chatty = prettyNix (stripAnnotation e)-          | otherwise = prettyNix (Fix (Fix (NSym "<?>") <$ x))+  let+    lvl :: Verbosity+    lvl = verbose opts++    expr :: NExpr+    expr = stripAnnotation e++    concise = prettyNix $ Fix $ Fix (NSym "<?>") <$ x++    chatty =+      bool+        (pretty $ PS.ppShow expr)+        (prettyNix expr)+        (lvl == Chatty)+   pure $     bool-      (pretty shortLabel <> fillSep [": ", rendered])-      (vsep [pretty (longLabel <> ":\n>>>>>>>>"), indent 2 rendered, "<<<<<<<<"])-      (verbose opts >= Chatty)+      (pretty shortLabel <> fillSep [": ", concise])+      (vsep [pretty (longLabel <> ":\n>>>>>>>>"), indent 2 chatty, "<<<<<<<<"])+      (lvl >= Chatty)  renderValueFrame   :: forall e t f m ann@@ -166,7 +180,7 @@   => NixLevel   -> ValueFrame t f m   -> m [Doc ann]-renderValueFrame level = fmap (: mempty) . \case+renderValueFrame level = fmap one . \case   ForcingThunk    _t -> pure "ForcingThunk" -- jww (2019-03-18): NYI   ConcerningValue _v -> pure "ConcerningValue"   Comparison     _ _ -> pure "Comparing"@@ -175,22 +189,23 @@   Multiplication _ _ -> pure "Multiplying"    Coercion       x y -> pure-    $ mconcat [desc, pretty (describeValue x), " to ", pretty (describeValue y)]+    $ fold [desc, pretty (describeValue x), " to ", pretty (describeValue y)]    where     desc =       bool-      "While coercing "-      "Cannot coerce "-      (level <= Error)+        "While coercing "+        "Cannot coerce "+        (level <= Error)    CoercionToJson v ->-    ("CoercionToJson " <>) <$> renderValue level "" "" v+    ("CoercionToJson " <>) <$> dumbRenderValue v   CoercionFromJson _j -> pure "CoercionFromJson"   Expectation t v     ->-    (msg <>) <$> renderValue @_ @t @f @m level "" "" v+    (msg <>) <$> dumbRenderValue v    where     msg = "Expected " <> pretty (describeValue t) <> ", but saw " +--  2021-10-28: NOTE: notice it ignores `level`, `longlabel` & `shortlabel`, to underline that `dumbRenderValue` synonym was created renderValue   :: forall e t f m ann    . (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)@@ -207,37 +222,34 @@     (values opts)     <$> removeEffects v +dumbRenderValue+  :: forall e t f m ann+   . (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)+   => (NValue t f m -> m (Doc ann))+dumbRenderValue = renderValue Info mempty mempty+ renderExecFrame   :: (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)   => NixLevel   -> ExecFrame t f m   -> m [Doc ann]-renderExecFrame level =-  \case-    Assertion ann v ->-      fmap-        (: mempty)-        (do-          d <- renderValue level "" "" v-          renderLocation ann $ fillSep ["Assertion failed:", d]-        )+renderExecFrame _level (Assertion ann v) =+  fmap+    one+    $ renderLocation ann . fillSep . on (<>) one "Assertion failed:" =<< dumbRenderValue v  renderThunkLoop   :: (MonadReader e m, Has e Options, MonadFile m, Show (ThunkId m))   => NixLevel   -> ThunkLoop   -> m [Doc ann]-renderThunkLoop _level = pure . (: mempty) . \case-  ThunkLoop n -> pretty $ "Infinite recursion in thunk " <> n+renderThunkLoop _level (ThunkLoop n) =+  pure . one . pretty $ "Infinite recursion in thunk " <> n  renderNormalLoop   :: (MonadReader e m, Has e Options, MonadFile m, MonadCitedThunks t f m)   => NixLevel   -> NormalLoop t f m   -> m [Doc ann]-renderNormalLoop level =-  fmap-    (: mempty)-    . \case-      NormalLoop v ->-        ("Infinite recursion during normalization forcing " <>) <$> renderValue level "" "" v+renderNormalLoop _level (NormalLoop v) =+  one . ("Infinite recursion during normalization forcing " <>) <$> dumbRenderValue v
src/Nix/Scope.hs view
@@ -1,26 +1,29 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language FunctionalDependencies #-}+{-# language GeneralizedNewtypeDeriving #-}  module Nix.Scope where  import qualified Data.HashMap.Lazy             as M import qualified Text.Show import           Lens.Family2-import           Nix.Utils+import           Nix.Expr.Types -newtype Scope a = Scope { getScope :: AttrSet a }-  deriving (Functor, Foldable, Traversable, Eq)+--  2021-07-19: NOTE: Scopes can gain from sequentiality, HashMap (aka AttrSet) may not be proper to it.+newtype Scope a = Scope (AttrSet a)+  deriving+    ( Eq, Ord, Generic+    , Typeable, NFData+    , Read, Hashable+    , Semigroup, Monoid+    , Functor, Foldable, Traversable+    )  instance Show (Scope a) where   show (Scope m) = show $ M.keys m -newScope :: AttrSet a -> Scope a-newScope = Scope--scopeLookup :: Text -> [Scope a] -> Maybe a+scopeLookup :: VarName -> [Scope a] -> Maybe a scopeLookup key = foldr go Nothing  where   go@@ -45,14 +48,14 @@ instance Monoid (Scopes m a) where   mempty = emptyScopes -emptyScopes :: forall m a . Scopes m a+emptyScopes :: Scopes m a emptyScopes = Scopes mempty mempty  class Scoped a m | m -> a where   currentScopes :: m (Scopes m a)   clearScopes   :: m r -> m r   pushScopes    :: Scopes m a -> m r -> m r-  lookupVar     :: Text -> m (Maybe a)+  lookupVar     :: VarName -> m (Maybe a)  currentScopesReader   :: forall m a e@@ -73,19 +76,19 @@  pushScope   :: Scoped a m-  => AttrSet a+  => Scope a   -> m r   -> m r-pushScope s = pushScopes $ Scopes [Scope s] mempty+pushScope scope = pushScopes $ Scopes (one scope) mempty  pushWeakScope   :: ( Functor m      , Scoped a m      )-  => m (AttrSet a)+  => m (Scope a)   -> m r   -> m r-pushWeakScope s = pushScopes $ Scopes mempty [Scope <$> s]+pushWeakScope scope = pushScopes $ Scopes mempty $ one scope  pushScopesReader   :: ( MonadReader e m@@ -101,7 +104,7 @@   . ( MonadReader e m     , Has e (Scopes m a)     )-  => Text+  => VarName   -> m (Maybe a) lookupVarReader k =   do@@ -112,9 +115,9 @@         ws <- asks $ dynamicScopes . view hasLens          foldr-          (\ x rest ->+          (\ weakscope rest ->             do-              mres' <- M.lookup k . getScope <$> x+              mres' <- M.lookup k . coerce @(Scope a) <$> weakscope                maybe                 rest@@ -132,4 +135,4 @@   => Scopes m a   -> m r   -> m r-withScopes scope = clearScopes . pushScopes scope+withScopes scopes = clearScopes . pushScopes scopes
src/Nix/Standard.hs view
@@ -1,15 +1,13 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE UndecidableInstances #-}+{-# language TypeFamilies #-}+{-# language CPP #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language UndecidableInstances #-} -{-# OPTIONS_GHC -Wno-orphans #-}+{-# options_ghc -Wno-orphans #-}   module Nix.Standard where -import           Prelude hiding                 ( force ) import           Control.Comonad                ( Comonad ) import           Control.Comonad.Env            ( ComonadEnv ) import           Control.Monad.Catch            ( MonadThrow@@ -19,7 +17,7 @@ #if !MIN_VERSION_base(4,13,0) import           Control.Monad.Fail             ( MonadFail ) #endif-import           Control.Monad.Free             ( Free(Pure, Free) )+import           Control.Monad.Free             ( Free(Free) ) import           Control.Monad.Reader           ( MonadFix ) import           Control.Monad.Ref              ( MonadRef(newRef)                                                 , MonadAtomicRef@@ -39,7 +37,6 @@ import           Nix.Scope import           Nix.Thunk import           Nix.Thunk.Basic-import           Nix.Utils                      ( free ) import           Nix.Utils.Fix1                 ( Fix1T(Fix1T) ) import           Nix.Value import           Nix.Value.Monad@@ -47,7 +44,7 @@  newtype StdCited m a =   StdCited-    { _stdCited :: Cited (StdThunk m) (StdCited m) m a }+    (Cited (StdThunk m) (StdCited m) m a)   deriving     ( Generic     , Typeable@@ -59,13 +56,18 @@     , ComonadEnv [Provenance m (StdValue m)]     ) -newtype StdThunk (m :: Type -> Type) =+newtype StdThunk m =   StdThunk-    { _stdThunk :: StdCited m (NThunkF m (StdValue m)) }+    (StdCited m (NThunkF m (StdValue m)))  type StdValue' m = NValue' (StdThunk m) (StdCited m) m (StdValue m) type StdValue m = NValue (StdThunk m) (StdCited m) m +-- | Type alias:+--+-- > Cited (StdThunk m) (StdCited m) m (NThunkF m (StdValue m))+type CitedStdThunk m = Cited (StdThunk m) (StdCited m) m (NThunkF m (StdValue m))+ instance Show (StdThunk m) where   show _ = toString thunkStubText @@ -100,13 +102,13 @@   , Typeable m   , Scoped (StdValue m) m   , MonadReader (Context m (StdValue m)) m-  , MonadState (HashMap FilePath NExprLoc, HashMap Text Text) m+  , MonadState (HashMap Path NExprLoc, HashMap Text Text) m   , MonadDataErrorContext (StdThunk m) (StdCited m) m   , MonadThunk (StdThunk m) m (StdValue m)   , MonadValue (StdValue m) m   )   => MonadEffects (StdThunk m) (StdCited m) m where-  makeAbsolutePath = defaultMakeAbsolutePath+  toAbsolutePath   = defaultToAbsolutePath   findEnvPath      = defaultFindEnvPath   findPath         = defaultFindPath   importPath       = defaultImportPath@@ -114,6 +116,10 @@   derivationStrict = defaultDerivationStrict   traceEffect      = defaultTraceEffect +-- 2021-07-24:+-- This instance currently is to satisfy @MonadThunk@ requirements for @normalForm@ function.+-- As it is seen from the instance - it does superficial type class jump.+-- It is just a type boundary for thunking. instance   ( Typeable       m   , MonadThunkId   m@@ -126,34 +132,39 @@   thunkId     :: StdThunk m     -> ThunkId  m-  thunkId = thunkId . _stdCited . _stdThunk+  thunkId = thunkId @(CitedStdThunk m) . coerce   {-# inline thunkId #-}    thunk     :: m (StdValue m)     -> m (StdThunk m)-  thunk = fmap (StdThunk . StdCited) . thunk+  thunk = fmap coerce . thunk @(CitedStdThunk m)+  {-# inline thunk #-}    query     :: m (StdValue m)     ->    StdThunk m     -> m (StdValue m)-  query b = query b . _stdCited . _stdThunk+  query b = query @(CitedStdThunk m) b . coerce+  {-# inline query #-}    force     ::    StdThunk m     -> m (StdValue m)-  force = force . _stdCited . _stdThunk+  force = force @(CitedStdThunk m) . coerce+  {-# inline force #-}    forceEff     ::    StdThunk m     -> m (StdValue m)-  forceEff = forceEff . _stdCited . _stdThunk+  forceEff = forceEff @(CitedStdThunk m) . coerce+  {-# inline forceEff #-}    further     ::    StdThunk m     -> m (StdThunk m)-  further = fmap (StdThunk . StdCited) . further . _stdCited . _stdThunk+  further = fmap coerce . further @(CitedStdThunk m) . coerce+  {-# inline further #-}   -- * @instance MonadThunkF@ (Kleisli functor HOFs)@@ -175,7 +186,7 @@     -> m r     -> StdThunk m     -> m r-  queryF k b = queryF k b . _stdCited . _stdThunk+  queryF k b = queryF @(CitedStdThunk m) k b . coerce    forceF     :: ( StdValue m@@ -183,7 +194,7 @@        )     -> StdThunk m     -> m r-  forceF k = forceF k . _stdCited . _stdThunk+  forceF k = forceF @(CitedStdThunk m) k . coerce    forceEffF     :: ( StdValue m@@ -191,7 +202,7 @@        )     -> StdThunk m     -> m r-  forceEffF k = forceEffF k . _stdCited . _stdThunk+  forceEffF k = forceEffF @(CitedStdThunk m) k . coerce    furtherF     :: ( m (StdValue m)@@ -199,7 +210,7 @@        )     ->    StdThunk m     -> m (StdThunk m)-  furtherF k = fmap (StdThunk . StdCited) . furtherF k . _stdCited . _stdThunk+  furtherF k = fmap coerce . furtherF @(CitedStdThunk m) k . coerce   -- * @instance MonadValue (StdValue m) m@@@ -216,22 +227,29 @@   defer     :: m (StdValue m)     -> m (StdValue m)-  defer = fmap pure . thunk+  defer = fmap (pure . coerce) . thunk @(CitedStdThunk m)    demand     :: StdValue m     -> m (StdValue m)-  demand v =-    free-      (demand <=< force)-      (const $ pure v)-      v+  demand = go -- lock to ensure no type class jumps.+   where+    go :: StdValue m -> m (StdValue m)+    go =+      free+        (go <=< force @(CitedStdThunk m) . coerce)+        (pure . Free)    inform     :: StdValue m     -> m (StdValue m)-  inform (Pure t) = Pure <$> further t-  inform (Free v) = Free <$> bindNValue' id inform v+  inform = go -- lock to ensure no type class jumps.+   where+    go :: StdValue m -> m (StdValue m)+    go =+      free+        ((pure . coerce <$>) . (further @(CitedStdThunk m) . coerce))+        ((Free <$>) . bindNValue' id go)   -- * @instance MonadValueF (StdValue m) m@@@ -271,8 +289,12 @@ --   withFrame Debug (ForcingThunk @t @f @m) . withFrame Debug frame  newtype StandardTF r m a-  = StandardTF (ReaderT (Context r (StdValue r))-                        (StateT (HashMap FilePath NExprLoc, HashMap Text Text) m) a)+  = StandardTF+      (ReaderT+        (Context r (StdValue r))+        (StateT (HashMap Path NExprLoc, HashMap Text Text) m)+        a+      )   deriving     ( Functor     , Applicative@@ -286,7 +308,7 @@     , MonadThrow     , MonadMask     , MonadReader (Context r (StdValue r))-    , MonadState (HashMap FilePath NExprLoc, HashMap Text Text)+    , MonadState (HashMap Path NExprLoc, HashMap Text Text)     )  instance MonadTrans (StandardTF r) where@@ -314,27 +336,28 @@  instance MonadTrans (Fix1T StandardTF) where   lift = Fix1T . lift+  {-# inline lift #-}  instance MonadThunkId m-  => MonadThunkId (Fix1T StandardTF m) where+  => MonadThunkId (StandardT m) where -  type ThunkId (Fix1T StandardTF m) = ThunkId m+  type ThunkId (StandardT m) = ThunkId m  mkStandardT   :: ReaderT       (Context (StandardT m) (StdValue (StandardT m)))-      (StateT (HashMap FilePath NExprLoc, HashMap Text Text) m)+      (StateT (HashMap Path NExprLoc, HashMap Text Text) m)       a   -> StandardT m a-mkStandardT = Fix1T . StandardTF+mkStandardT = coerce  runStandardT   :: StandardT m a   -> ReaderT       (Context (StandardT m) (StdValue (StandardT m)))-      (StateT (HashMap FilePath NExprLoc, HashMap Text Text) m)+      (StateT (HashMap Path NExprLoc, HashMap Text Text) m)       a-runStandardT (Fix1T (StandardTF m)) = m+runStandardT = coerce  runWithBasicEffects   :: (MonadIO m, MonadAtomicRef m)
src/Nix/String.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# language GeneralizedNewtypeDeriving #-}  module Nix.String   ( NixString   , getContext-  , makeNixString+  , mkNixString   , StringContext(..)   , ContextFlavor(..)   , NixLikeContext(..)@@ -14,8 +14,8 @@   , intercalateNixString   , getStringNoContext   , stringIgnoreContext-  , makeNixStringWithoutContext-  , makeNixStringWithSingletonContext+  , mkNixStringWithoutContext+  , mkNixStringWithSingletonContext   , modifyNixContents   , WithStringContext   , WithStringContextT(..)@@ -32,21 +32,24 @@   -import           Nix.Utils import           Control.Monad.Writer           ( WriterT(..), MonadWriter(tell)) import qualified Data.HashMap.Lazy             as M import qualified Data.HashSet                  as S import qualified Data.Text                     as Text+import           Nix.Expr.Types                 ( VarName(..)+                                                , AttrSet+                                                )   -- * Types  -- ** Context +--  2021-07-18: NOTE: it should be ContextFlavor -> Varname. -- | A Nix 'StringContext' ... data StringContext =   StringContext-    { scPath :: !Text+    { scPath :: !VarName     , scFlavor :: !ContextFlavor     }   deriving (Eq, Ord, Show, Generic)@@ -101,6 +104,7 @@  -- ** NixString +--  2021-07-18: NOTE: It should be Context -> Contents. data NixString =   NixString     { nsContents :: !Text@@ -122,17 +126,17 @@ -- ** Makers  -- | Constructs NixString without a context-makeNixStringWithoutContext :: Text -> NixString-makeNixStringWithoutContext = (`NixString` mempty)+mkNixStringWithoutContext :: Text -> NixString+mkNixStringWithoutContext = (`NixString` mempty)  -- | Create NixString using a singleton context-makeNixStringWithSingletonContext-  :: Text -> StringContext -> NixString-makeNixStringWithSingletonContext s c = NixString s $ one c+mkNixStringWithSingletonContext+  :: VarName -> StringContext -> NixString+mkNixStringWithSingletonContext s c = NixString (coerce @VarName @Text s) $ one c  -- | Create NixString from a Text and context-makeNixString :: Text -> S.HashSet StringContext -> NixString-makeNixString = NixString+mkNixString :: Text -> S.HashSet StringContext -> NixString+mkNixString = NixString   -- ** Checkers@@ -172,7 +176,7 @@  -- this really should be 2 args, then with @toStringContexts path@ laziness it would tail recurse. -- for now tuple dissected internaly with laziness preservation.-toStringContexts :: (Text, NixLikeContextValue) -> [StringContext]+toStringContexts :: (VarName, NixLikeContextValue) -> [StringContext] toStringContexts ~(path, nlcv) =   go nlcv  where@@ -190,13 +194,13 @@     mkCtxFor = StringContext path     mkLstCtxFor t c = mkCtxFor t : go c -toNixLikeContextValue :: StringContext -> (Text, NixLikeContextValue)+toNixLikeContextValue :: StringContext -> (VarName, NixLikeContextValue) toNixLikeContextValue sc =   ( scPath sc   , case scFlavor sc of       DirectPath         -> NixLikeContextValue True False mempty       AllOutputs         -> NixLikeContextValue False True mempty-      DerivationOutput t -> NixLikeContextValue False False [t]+      DerivationOutput t -> NixLikeContextValue False False $ one t   )  toNixLikeContext :: S.HashSet StringContext -> NixLikeContext
src/Nix/String/Coerce.hs view
@@ -1,8 +1,9 @@-{-# LANGUAGE CPP #-}+{-# language CPP #-}  module Nix.String.Coerce where  import           Control.Monad.Catch            ( MonadThrow )+import           GHC.Exception                  ( ErrorCall(ErrorCall) ) import qualified Data.HashMap.Lazy             as M import           Nix.Atoms import           Nix.Effects@@ -58,11 +59,7 @@         case x' of           -- TODO Return a singleton for "" and "1"           NVConstant (NBool b) ->-            castToNixString $-              bool-                ""-                "1"-                b+            castToNixString $ "1" `whenTrue` b           NVConstant (NInt n) ->             castToNixString $               show n@@ -70,10 +67,10 @@             castToNixString $               show n           NVConstant NNull ->-            castToNixString ""+            castToNixString mempty           -- NVConstant: NAtom (NURI Text) is not matched           NVList l ->-            nixStringUnwords <$> traverse (go <=< demand) l+            nixStringUnwords <$> traverse go l           v -> coerceStringy v        coerceStringy x' =@@ -81,11 +78,11 @@           NVStr ns -> pure ns           NVPath p ->             bool-              (castToNixString . toText)+              (castToNixString . fromString . coerce)               (fmap storePathToNixString . addPath)               (ctsm == CopyToStore)               p-          v@(NVSet s _) ->+          v@(NVSet _ s) ->             maybe               (maybe                 (err v)@@ -106,15 +103,15 @@            v -> err v       err v = throwError $ ErrorCall $ "Expected a string, but saw: " <> show v-      castToNixString = pure . makeNixStringWithoutContext+      castToNixString = pure . mkNixStringWithoutContext -  nixStringUnwords = intercalateNixString $ makeNixStringWithoutContext " "+  nixStringUnwords = intercalateNixString $ mkNixStringWithoutContext " "    storePathToNixString :: StorePath -> NixString   storePathToNixString sp =-    makeNixStringWithSingletonContext+    mkNixStringWithSingletonContext       t       (StringContext t DirectPath)    where-    t = toText $ unStorePath sp+    t = fromString $ coerce sp 
src/Nix/TH.hs view
@@ -1,92 +1,113 @@-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-} -{-# OPTIONS_GHC -Wno-missing-fields #-}+{-# options_ghc -Wno-missing-fields #-}+{-# options_ghc -Wno-name-shadowing #-}  module Nix.TH where -import           Data.Fix                       ( Fix(..) )+import           Data.Fix                       ( Fix(unFix) ) import           Data.Generics.Aliases          ( extQ ) import qualified Data.Set                      as Set import           Language.Haskell.TH import qualified Language.Haskell.TH.Syntax    as TH import           Language.Haskell.TH.Quote import           Nix.Atoms-import           Nix.Expr+import           Nix.Expr.Types+import           Nix.Expr.Types.Annotated import           Nix.Parser  quoteExprExp :: String -> ExpQ-quoteExprExp s = do-  expr <--    either-      (fail . show)-      pure-      (parseNixText $ toText s)-  dataToExpQ-    (const Nothing `extQ` metaExp (freeVars expr) `extQ` (pure . (TH.lift :: Text -> Q Exp)))-    expr+quoteExprExp s =+  do+    expr <- parseExpr $ fromString s+    dataToExpQ+      (extQOnFreeVars metaExp expr `extQ` (pure . (TH.lift :: Text -> Q Exp)))+      expr  quoteExprPat :: String -> PatQ-quoteExprPat s = do-  expr <--    either-      (fail . show)-      pure-      (parseNixText $ toText s)-  dataToPatQ-    (const Nothing `extQ` metaPat (freeVars expr))-    expr+quoteExprPat s =+  do+    expr <- parseExpr $ fromString s+    dataToPatQ+      (extQOnFreeVars metaPat expr)+      expr +-- | Helper function.+extQOnFreeVars+  :: ( Typeable b+    , Typeable loc+    )+  => ( Set VarName+    -> loc+    -> Maybe q+    )+  -> NExpr+  -> b+  -> Maybe q+extQOnFreeVars f = extQ (const Nothing) . f . freeVars++parseExpr :: (MonadFail m) => Text -> m NExpr+parseExpr =+  either+    (fail . show)+    pure+    . parseNixText+ freeVars :: NExpr -> Set VarName freeVars e = case unFix e of   (NConstant    _               ) -> mempty   (NStr         string          ) -> mapFreeVars string   (NSym         var             ) -> one var   (NList        list            ) -> mapFreeVars list-  (NSet   NNonRecursive bindings) -> bindFreeVars bindings-  (NSet   NRecursive    bindings) -> Set.difference (bindFreeVars bindings) (bindDefs bindings)+  (NSet   NonRecursive  bindings) -> bindFreeVars bindings+  (NSet   Recursive     bindings) -> diffBetween bindFreeVars bindDefs bindings   (NLiteralPath _               ) -> mempty   (NEnvPath     _               ) -> mempty   (NUnary       _    expr       ) -> freeVars expr-  (NBinary      _    left right ) -> ((<>) `on` freeVars) left right-  (NSelect      expr path orExpr) ->+  (NBinary      _    left right ) -> collectFreeVars left right+  (NSelect      orExpr expr path) ->     Set.unions       [ freeVars expr       , pathFree path-      , maybe mempty freeVars orExpr+      , freeVars `whenJust` orExpr       ]   (NHasAttr expr            path) -> freeVars expr <> pathFree path   (NAbs     (Param varname) expr) -> Set.delete varname (freeVars expr)-  (NAbs (ParamSet set _ varname) expr) ->+  (NAbs (ParamSet varname _ pset) expr) ->     -- Include all free variables from the expression and the default arguments     freeVars expr <>     -- But remove the argument name if existing, and all arguments in the parameter set     Set.difference-      (Set.unions $ freeVars <$> mapMaybe snd set)+      (Set.unions $ freeVars <$> mapMaybe snd pset)       (Set.difference-        (maybe mempty one varname)-        (Set.fromList $ fst <$> set)+        (one `whenJust` varname)+        (Set.fromList $ fst <$> pset)       )   (NLet         bindings expr   ) ->     freeVars expr <>-    Set.difference-      (bindFreeVars bindings)-      (bindDefs  bindings)+    diffBetween bindFreeVars bindDefs bindings   (NIf          cond th   el    ) -> Set.unions $ freeVars <$> [cond, th, el]   -- Evaluation is needed to find out whether x is a "real" free variable in `with y; x`, we just include it   -- This also makes sense because its value can be overridden by `x: with y; x`-  (NWith        set  expr       ) -> ((<>) `on` freeVars) set expr-  (NAssert      assertion expr  ) -> ((<>) `on` freeVars) assertion expr+  (NWith        set  expr       ) -> collectFreeVars set expr+  (NAssert      assertion expr  ) -> collectFreeVars assertion expr   (NSynHole     _               ) -> mempty   where +  diffBetween :: (a -> Set VarName) -> (a -> Set VarName) -> a -> Set VarName+  diffBetween g f b = Set.difference (g b) (f b)++  collectFreeVars :: NExpr -> NExpr -> Set VarName+  collectFreeVars = (<>) `on` freeVars+   bindDefs :: Foldable t => t (Binding NExpr) -> Set VarName   bindDefs = foldMap bind1Def    where     bind1Def :: Binding r -> Set VarName     bind1Def (Inherit   Nothing                  _    _) = mempty-    bind1Def (Inherit  (Just _                 ) keys _) = Set.fromList $ mapMaybe staticKey keys+    bind1Def (Inherit  (Just _                 ) keys _) = Set.fromList keys     bind1Def (NamedVar (StaticKey  varname :| _) _    _) = one varname     bind1Def (NamedVar (DynamicKey _       :| _) _    _) = mempty @@ -94,14 +115,10 @@   bindFreeVars = foldMap bind1Free    where     bind1Free :: Binding NExpr -> Set VarName-    bind1Free (Inherit  Nothing     keys _) = Set.fromList $ mapMaybe staticKey keys+    bind1Free (Inherit  Nothing     keys _) = Set.fromList keys     bind1Free (Inherit (Just scope) _    _) = freeVars scope     bind1Free (NamedVar path        expr _) = pathFree path <> freeVars expr -  staticKey :: NKeyName r -> Maybe VarName-  staticKey (StaticKey  varname) = pure varname-  staticKey (DynamicKey _      ) = mempty-   pathFree :: NAttrPath NExpr -> Set VarName   pathFree = foldMap mapFreeVars @@ -116,24 +133,24 @@   toExpr = id  instance ToExpr VarName where-  toExpr = Fix . NSym_ nullSpan+  toExpr = NSymAnn nullSpan  instance ToExpr Int where-  toExpr = Fix . NConstant_ nullSpan . NInt . fromIntegral+  toExpr = NConstantAnn nullSpan . NInt . fromIntegral  instance ToExpr Integer where-  toExpr = Fix . NConstant_ nullSpan . NInt+  toExpr = NConstantAnn nullSpan . NInt  instance ToExpr Float where-  toExpr = Fix . NConstant_ nullSpan . NFloat+  toExpr = NConstantAnn nullSpan . NFloat  metaExp :: Set VarName -> NExprLoc -> Maybe ExpQ-metaExp fvs (Fix (NSym_ _ x)) | x `Set.member` fvs =+metaExp fvs (NSymAnn _ x) | x `Set.member` fvs =   pure [| toExpr $(varE (mkName $ toString x)) |] metaExp _ _ = Nothing  metaPat :: Set VarName -> NExprLoc -> Maybe PatQ-metaPat fvs (Fix (NSym_ _ x)) | x `Set.member` fvs =+metaPat fvs (NSymAnn _ x) | x `Set.member` fvs =   pure $ varP $ mkName $ toString x metaPat _ _ = Nothing 
src/Nix/Thunk.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE DefaultSignatures #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE TypeFamilies #-}+{-# language DefaultSignatures #-}+{-# language FunctionalDependencies #-}+{-# language TypeFamilies #-}  module Nix.Thunk where 
src/Nix/Thunk/Basic.hs view
@@ -1,7 +1,6 @@-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE UndecidableInstances #-}-{-# OPTIONS_GHC -Wno-unused-do-bind #-}+{-# language ConstraintKinds #-}+{-# language UndecidableInstances #-}+{-# options_ghc -Wno-unused-do-bind #-}   module Nix.Thunk.Basic@@ -11,8 +10,6 @@   , MonadBasicThunk   ) where -import           Prelude                 hiding ( force )-import           Relude.Extra                   ( dup ) import           Control.Monad.Ref              ( MonadRef(Ref, newRef, readRef, writeRef)                                                 , MonadAtomicRef(atomicModifyRef)                                                 )
src/Nix/Type/Assumption.hs view
@@ -1,6 +1,6 @@ -- | Basing on the Nix (Hindley–Milner) type system (that provides decidable type inference): -- gathering assumptions (inference evidence) about polymorphic types.-{-# LANGUAGE TypeFamilies #-}+{-# language TypeFamilies #-} module Nix.Type.Assumption   ( Assumption(..)   , empty@@ -9,7 +9,6 @@   , extend   , keys   , merge-  , mergeAssumptions   , singleton   ) where@@ -18,9 +17,10 @@                                                 , empty                                                 ) +import           Nix.Expr.Types import           Nix.Type.Type -newtype Assumption = Assumption { assumptions :: [(Name, Type)] }+newtype Assumption = Assumption [(VarName, Type)]   deriving (Eq, Show)  -- We pretend that Assumptions can be inconsistent (nonunique keys),@@ -33,40 +33,40 @@   mempty = empty  instance One Assumption where-  type OneItem Assumption = (Name, Type)-  one (x, y) = Assumption [(x, y)]+  type OneItem Assumption = (VarName, Type)+  one vt = Assumption $ one vt  empty :: Assumption empty = Assumption mempty -extend :: Assumption -> (Name, Type) -> Assumption-extend (Assumption a) (x, s) =-  Assumption $-    (x, s) : a+extend :: Assumption -> (VarName, Type) -> Assumption+extend a vt =+  one (coerce vt) <> a -remove :: Assumption -> Name -> Assumption-remove (Assumption a) var =-  Assumption $+remove :: Assumption -> VarName -> Assumption+remove a var =+  coerce+    rmVar+    a+ where+  rmVar :: [(VarName, Type)] -> [(VarName, Type)]+  rmVar =     filter-      (\(n, _) -> n /= var)-      a+      ((/=) var . fst) -lookup :: Name -> Assumption -> [Type]-lookup key (Assumption a) =+lookup :: VarName -> Assumption -> [Type]+lookup key a =   snd <$>     filter-      (\(n, _) -> n == key)-      a+      ((==) key . fst)+      (coerce a)  merge :: Assumption -> Assumption -> Assumption-merge (Assumption a) (Assumption b) =-  Assumption $ a <> b--mergeAssumptions :: [Assumption] -> Assumption-mergeAssumptions = foldl' (<>) mempty+merge =+  coerce ((<>) @[(VarName, Type)]) -singleton :: Name -> Type -> Assumption-singleton x y = Assumption [(x, y)]+singleton :: VarName -> Type -> Assumption+singleton = curry one -keys :: Assumption -> [Name]+keys :: Assumption -> [VarName] keys (Assumption a) = fst <$> a
src/Nix/Type/Env.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeFamilies #-}+{-# language TypeFamilies #-} module Nix.Type.Env   ( Env(..)   , empty@@ -20,6 +20,7 @@                                                 , fromList                                                 ) +import           Nix.Expr.Types import           Nix.Type.Type  import qualified Data.Map                      as Map@@ -27,7 +28,7 @@  -- * Typing Environment -newtype Env = TypeEnv (Map.Map Name [Scheme])+newtype Env = TypeEnv (Map VarName [Scheme])   deriving (Eq, Show)  instance Semigroup Env where@@ -39,42 +40,42 @@   mempty = empty  instance One Env where-  type OneItem Env = (Name, Scheme)-  one = uncurry singleton+  type OneItem Env = (VarName, Scheme)+  one (x, y) = TypeEnv $ one (x, one y)  empty :: Env empty = TypeEnv mempty -extend :: Env -> (Name, [Scheme]) -> Env-extend env (x, s) = TypeEnv $ Map.insert x s $ coerce env+extend :: Env -> (VarName, [Scheme]) -> Env+extend env (x, s) = coerce (Map.insert x s) env -remove :: Env -> Name -> Env-remove (TypeEnv env) var = TypeEnv $ Map.delete var env+remove :: Env -> VarName -> Env+remove env var = TypeEnv $ Map.delete var $ coerce env -extends :: Env -> [(Name, [Scheme])] -> Env-extends env xs = TypeEnv $ Map.fromList xs <> coerce env+extends :: Env -> [(VarName, [Scheme])] -> Env+extends env xs = fromList xs <> coerce env -lookup :: Name -> Env -> Maybe [Scheme]-lookup key (TypeEnv tys) = Map.lookup key tys+lookup :: VarName -> Env -> Maybe [Scheme]+lookup key tys = Map.lookup key $ coerce tys  merge :: Env -> Env -> Env-merge (TypeEnv a) (TypeEnv b) = TypeEnv $ a <> b+merge a b = TypeEnv $ coerce a <> coerce b  mergeRight :: Env -> Env -> Env-mergeRight (TypeEnv a) (TypeEnv b) = TypeEnv $ b <> a+mergeRight = flip merge  mergeEnvs :: [Env] -> Env mergeEnvs = foldl' (<>) mempty -singleton :: Name -> Scheme -> Env-singleton x y = TypeEnv $ one (x, [y])+singleton :: VarName -> Scheme -> Env+singleton = curry one -keys :: Env -> [Name]+keys :: Env -> [VarName] keys (TypeEnv env) = Map.keys env -fromList :: [(Name, [Scheme])] -> Env-fromList xs = TypeEnv $ Map.fromList xs+fromList :: [(VarName, [Scheme])] -> Env+fromList xs = coerce $ Map.fromList xs -toList :: Env -> [(Name, [Scheme])]+toList :: Env -> [(VarName, [Scheme])] toList (TypeEnv env) = Map.toList env 
src/Nix/Type/Infer.hs view
@@ -1,14 +1,13 @@-{-# LANGUAGE MultiWayIf #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}+{-# language MultiWayIf #-}+{-# language CPP #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language ExistentialQuantification #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language RankNTypes #-}+{-# language TypeFamilies #-} -{-# OPTIONS_GHC -Wno-name-shadowing #-}+{-# options_ghc -Wno-name-shadowing #-}  module Nix.Type.Infer   ( Constraint(..)@@ -22,12 +21,11 @@ import           Control.Monad.Catch            ( MonadThrow(..)                                                 , MonadCatch(..)                                                 )-import           Control.Monad.Except           ( MonadError(..) )+import           Control.Monad.Except           ( MonadError(throwError,catchError) ) import           Prelude                 hiding ( Type                                                 , TVar                                                 , Constraint                                                 )-import           Nix.Utils import           Control.Monad.Logic     hiding ( fail ) import           Control.Monad.Reader           ( MonadFix ) import           Control.Monad.Ref              ( MonadAtomicRef(..)@@ -37,7 +35,6 @@                                                 , runST                                                 ) import           Data.Fix                       ( foldFix )-import           Data.Foldable                  ( foldrM ) import qualified Data.HashMap.Lazy             as M import           Data.List                      ( delete                                                 , intersect@@ -56,13 +53,10 @@                                                 , evalWithAttrSet                                                 ) import           Nix.Expr.Types-import           Nix.Expr.Types.Annotated import           Nix.Fresh import           Nix.String import           Nix.Scope-import           Nix.Type.Assumption     hiding ( assumptions-                                                , extend-                                                )+import           Nix.Type.Assumption     hiding ( extend ) import qualified Nix.Type.Assumption           as Assumption                                                 ( remove                                                 , lookup@@ -80,14 +74,14 @@   ord =     zip       (ordNub $ fv body)-      (TV . toText <$> letters)+      (TV . fromString <$> letters) -  fv (TVar a  ) = [a]-  fv (a :~> b ) = fv a <> fv b+  fv (TVar a  ) = one a+  fv (a :~> b ) = on (<>) fv a b   fv (TCon _  ) = mempty-  fv (TSet _ a) = concatMap fv $ M.elems a-  fv (TList a ) = concatMap fv a-  fv (TMany ts) = concatMap fv ts+  fv (TSet _ a) = foldMap fv $ M.elems a+  fv (TList a ) = foldMap fv a+  fv (TMany ts) = foldMap fv ts    normtype (a :~> b ) = normtype a :~> normtype b   normtype (TCon a  ) = TCon a@@ -109,6 +103,7 @@ closeOver :: Type -> Scheme closeOver = normalizeScheme . generalize mempty +-- When `[]` becomes `NonEmpty` - function becomes just `all` -- | Check if all elements are of the same type. allSameType :: [Type] -> Bool allSameType = allSame@@ -122,7 +117,7 @@ data TypeError   = UnificationFail Type Type   | InfiniteType TVar Type-  | UnboundVariables [Text]+  | UnboundVariables [VarName]   | Ambigious [Constraint]   | UnificationMismatch [Type] [Type]   deriving (Eq, Show, Ord)@@ -135,7 +130,7 @@   | forall s. Exception s => EvaluationError s  typeError :: MonadError InferError m => TypeError -> m ()-typeError err = throwError $ TypeInferenceErrors [err]+typeError err = throwError $ TypeInferenceErrors $ one err  -- ** Instances @@ -143,20 +138,27 @@ instance Exception InferError  instance Semigroup InferError where-  x <> _ = x+  (<>) = const  instance Monoid InferError where   mempty  = TypeInferenceAborted-  mappend = (<>)  -- * @InferState@: inference state --- | Inference state-newtype InferState = InferState { count :: Int }+-- | Inference state (stage).+newtype InferState = InferState Int+ deriving+  (Eq, Num, Enum, Ord) +instance Semigroup InferState where+  (<>) = (+)++instance Monoid InferState where+  mempty = 0+ -- | Initial inference state initInfer :: InferState-initInfer = InferState { count = 0 }+initInfer = InferState 0  letters :: [String] letters =@@ -170,18 +172,19 @@ freshTVar =   do     s <- get-    put s { count = count s + 1 }-    pure $ TV $ toText $ letters !! count s+    put $ succ s+    pure $ TV $ fromString $ letters !! coerce s  fresh :: MonadState InferState m => m Type fresh = TVar <$> freshTVar +intoFresh :: (Traversable t, MonadState InferState f) => t a -> f (t Type)+intoFresh =+  traverse (const fresh)+ instantiate :: MonadState InferState m => Scheme -> m Type instantiate (Forall as t) =-  do-    as' <- traverse (const fresh) as-    let s = Subst $ Map.fromList $ zip as as'-    pure $ apply s t+  fmap ((`apply` t) . coerce . Map.fromList . zip as) (intoFresh as)  -- * @Constraint@ data type @@ -199,9 +202,9 @@  -- | Compose substitutions compose :: Subst -> Subst -> Subst-Subst s1 `compose` Subst s2 =-  Subst $-    apply (Subst s1) <$>+compose a@(Subst s2) (Subst s1) =+  coerce $ --+    apply a <$>       (s2 <> s1)  -- * class @Substitutable@@@ -214,15 +217,14 @@ instance Substitutable TVar where   apply (Subst s) a = tv    where-    t         = TVar a-    (TVar tv) = Map.findWithDefault t a s+    (TVar tv) = Map.findWithDefault (TVar a) a s  instance Substitutable Type where   apply _         (  TCon a   ) = TCon a   apply s         (  TSet b a ) = TSet b $ apply s <$> a   apply s         (  TList a  ) = TList  $ apply s <$> a   apply (Subst s) t@(TVar  a  ) = Map.findWithDefault t a s-  apply s         (  t1 :~> t2) = apply s t1 :~> apply s t2+  apply s         (  t1 :~> t2) = ((:~>) `on` apply s) t1 t2   apply s         (  TMany ts ) = TMany  $ apply s <$> ts  instance Substitutable Scheme where@@ -231,10 +233,7 @@     s' = Subst $ foldr Map.delete s as  instance Substitutable Constraint where-  apply s (EqConst      t1 t2) =-    EqConst-      (apply s t1)-      (apply s t2)+  apply s (EqConst      t1 t2) = on EqConst (apply s) t1 t2   apply s (ExpInstConst t  sc) =     ExpInstConst       (apply s t)@@ -252,7 +251,7 @@   apply = Set.map . apply  --- * data type @Judgement@+-- * data type @Judgment@  data Judgment s =   Judgment@@ -262,16 +261,22 @@     }     deriving Show +inferred :: Type -> Judgment s+inferred = Judgment mempty mempty+ -- * @InferT@: inference monad +type InferTInternals s m a =+  ReaderT+    (Set.Set TVar, Scopes (InferT s m) (Judgment s))+    (StateT InferState (ExceptT InferError m))+    a+ -- | Inference monad newtype InferT s m a =   InferT     { getInfer ::-        ReaderT-          (Set.Set TVar, Scopes (InferT s m) (Judgment s))-          (StateT InferState (ExceptT InferError m))-          a+        InferTInternals s m a     }     deriving       ( Functor@@ -286,8 +291,11 @@       , MonadError InferError       ) -extendMSet :: Monad m => TVar -> InferT s m a -> InferT s m a-extendMSet x = InferT . local (first $ Set.insert x) . getInfer+extendMSet :: forall s m a . Monad m => TVar -> InferT s m a -> InferT s m a+extendMSet x = coerce putSetElementM+ where+  putSetElementM :: InferTInternals s m a -> InferTInternals s m a+  putSetElementM = local (first . Set.insert $ x)  -- ** Instances @@ -335,58 +343,48 @@ instance   MonadInfer m   => FromValue ( AttrSet (Judgment s)-              , AttrSet SourcePos+              , PositionSet               ) (InferT s m) (Judgment s)  where   fromValueMay (Judgment _ _ (TSet _ xs)) =     do-      let sing _ = Judgment mempty mempty+      let sing = const inferred       pure $ pure (M.mapWithKey sing xs, mempty)   fromValueMay _ = stub   fromValue =     pure .-      fromMaybe-      (mempty, mempty)+      maybeToMonoid       <=< fromValueMay -instance MonadInfer m-  => ToValue (AttrSet (Judgment s), AttrSet SourcePos)-            (InferT s m) (Judgment s) where-  toValue (xs, _) =-    liftA3-      Judgment-      (foldrM go mempty xs)-      (fun concat      typeConstraints)-      (fun (TSet True) inferredType   )+foldInitializedWith :: (Traversable t, Applicative f) => (t c -> c) -> (b -> c) -> (a -> f b) -> t a -> f c+foldInitializedWith fld getter init =+  -- maybe here is some law?+  fmap fld . traverse (fmap getter . init)++toJudgment :: forall t m s . (Traversable t, Monad m) => (t Type -> Type) -> t (Judgment s) -> InferT s m (Judgment s)+toJudgment c xs =+  liftA3 Judgment+    (foldWith fold assumptions    )+    (foldWith fold typeConstraints)+    (foldWith c    inferredType   )    where-    go x rest =-      do-        x' <- demand x-        pure $ assumptions x' <> rest+    foldWith :: ((t a -> a) -> (Judgment s -> a) -> InferT s m a)+    foldWith g f = uncurry (foldInitializedWith g f) tpl -    fun :: (AttrSet b -> b1) -> (Judgment s -> b) -> InferT s m b1-    fun g f =-      g <$> traverse ((f <$>) . demand) xs+    tpl :: (Judgment s -> InferT s m (Judgment s), t (Judgment s))+    tpl = (demand, xs) -instance MonadInfer m => ToValue [Judgment s] (InferT s m) (Judgment s) where-  toValue xs =-    liftA3-      Judgment-      (foldrM go mempty xs)-      (fun concat typeConstraints)-      (fun TList  inferredType   )-   where-    go x rest =-      do-        x' <- demand x-        pure $ assumptions x' <> rest+instance MonadInfer m+  => ToValue (AttrSet (Judgment s), PositionSet)+            (InferT s m) (Judgment s) where+  toValue :: (AttrSet (Judgment s), PositionSet) -> InferT s m (Judgment s)+  toValue (xs, _) = toJudgment (TSet Variadic) xs -- why variadic? Probably `Closed` (`mempty`)? -    fun :: ([b] -> b1) -> (Judgment s -> b) -> InferT s m b1-    fun g f =-      g <$> traverse ((f <$>) . demand) xs+instance MonadInfer m => ToValue [Judgment s] (InferT s m) (Judgment s) where+  toValue = toJudgment TList  instance MonadInfer m => ToValue Bool (InferT s m) (Judgment s) where-  toValue _ = pure $ Judgment mempty mempty typeBool+  toValue _ = pure $ inferred typeBool  instance   Monad m@@ -424,7 +422,7 @@       -> InferT s m r)     -> Judgment s     -> InferT s m r-  demandF f a = f a+  demandF f = f    informF     :: ( InferT s m (Judgment s)@@ -455,84 +453,84 @@                            f =<< Judgment mempty mempty <$> fresh -} +polymorphicVar :: MonadInfer m => VarName -> InferT s m (Judgment s)+polymorphicVar var =+    fmap+      (join ((`Judgment` mempty) . curry one var))+      fresh++constInfer :: Applicative f => Type -> b -> f (Judgment s)+constInfer x = const $ pure $ inferred x+ instance MonadInfer m => MonadEval (Judgment s) (InferT s m) where-  freeVariable var = do-    tv <- fresh-    pure $ Judgment (one (var, tv)) mempty tv+  freeVariable = polymorphicVar -  synHole var = do-    tv <- fresh-    pure $ Judgment (one (var, tv)) mempty tv+  synHole = polymorphicVar    -- If we fail to look up an attribute, we just don't know the type.-  attrMissing _ _ = Judgment mempty mempty <$> fresh+  attrMissing _ _ = inferred <$> fresh    evaledSym _ = pure    evalCurPos =     pure $-      Judgment-        mempty-        mempty-        (TSet False $+      inferred $+        TSet mempty $           M.fromList             [ ("file", typePath)             , ("line", typeInt )             , ("col" , typeInt )             ]-        ) -  evalConstant c = pure $ Judgment mempty mempty $ go c+  evalConstant c = pure $ inferred $ fun c    where-    go = \case+    fun = \case       NURI   _ -> typeString       NInt   _ -> typeInt       NFloat _ -> typeFloat       NBool  _ -> typeBool       NNull    -> typeNull -  evalString      = const $ pure $ Judgment mempty mempty typeString-  evalLiteralPath = const $ pure $ Judgment mempty mempty typePath-  evalEnvPath     = const $ pure $ Judgment mempty mempty typePath+  evalString      = constInfer typeString+  evalLiteralPath = constInfer typePath+  evalEnvPath     = constInfer typePath -  evalUnary op (Judgment as1 cs1 t1) = do-    tv <- fresh-    pure $-      Judgment-        as1-        (cs1 <> unops (t1 :~> tv) op)-        tv+  evalUnary op (Judgment as1 cs1 t1) =+    fmap+      (join+        $ Judgment+            as1+            . (cs1 <>) . (`unops` op) . (t1 :~>)+      )+      fresh    evalBinary op (Judgment as1 cs1 t1) e2 = do     Judgment as2 cs2 t2 <- e2-    tv                  <- fresh-    pure $-      Judgment-        (as1 <> as2)-        ( cs1 <>-          cs2 <>-          binops-            (t1 :~> t2 :~> tv)-            op-        )-        tv+    fmap+      (join+        $ Judgment+          (as1 <> as2)+          . (\ cs3 -> cs1 <> cs2 <> cs3) . (`binops` op) . (\ t3 -> t1 :~> t2 :~> t3)+      )+      fresh    evalWith = Eval.evalWithAttrSet    evalIf (Judgment as1 cs1 t1) t f = do     Judgment as2 cs2 t2 <- t     Judgment as3 cs3 t3 <- f-    pure $ Judgment-      (as1 <> as2 <> as3)-      (cs1 <> cs2 <> cs3 <> [EqConst t1 typeBool, EqConst t2 t3])-      t2+    pure $+      Judgment+        (as1 <> as2 <> as3)+        (cs1 <> cs2 <> cs3 <> [EqConst t1 typeBool, EqConst t2 t3])+        t2    evalAssert (Judgment as1 cs1 t1) body = do     Judgment as2 cs2 t2 <- body     pure $       Judgment         (as1 <> as2)-        (cs1 <> cs2 <> [EqConst t1 typeBool])+        (cs1 <> cs2 <> one (EqConst t1 typeBool))         t2    evalApp (Judgment as1 cs1 t1) e2 = do@@ -541,7 +539,7 @@     pure $       Judgment         (as1 <> as2)-        (cs1 <> cs2 <> [EqConst t1 (t2 :~> tv)])+        (cs1 <> cs2 <> one (EqConst t1 (t2 :~> tv)))         tv    evalAbs (Param x) k = do@@ -565,27 +563,19 @@         (cs <> [ EqConst t' tv | t' <- Assumption.lookup x as ])         (tv :~> t) -  evalAbs (ParamSet ps variadic _mname) k = do-    js <--      concat <$>-        traverse-          (\(name, _) ->-            do-              tv <- fresh-              pure [(name, tv)]-          )-          ps+  evalAbs (ParamSet _mname variadic pset) k = do+    js <- foldInitializedWith fold one intoFresh pset      let       f (as1, t1) (k, t) = (as1 <> one (k, t), M.insert k t t1)-      (env, tys) = foldl' f (mempty, mempty) js-      arg   = pure $ Judgment env mempty $ TSet True tys+      (env, tys) = foldl' f mempty js+      arg   = pure $ Judgment env mempty $ TSet Variadic tys       call  = k arg $ \args b -> (args, ) <$> b       names = fst <$> js      (args, Judgment as cs t) <- foldr (\(_, TVar a) -> extendMSet a) call js -    ty <- TSet variadic <$> traverse (inferredType <$>) args+    ty <- foldInitializedWith (TSet variadic) inferredType id args      pure $       Judgment@@ -651,7 +641,7 @@ runInfer' =   runExceptT     . (`evalStateT` initInfer)-    . (`runReaderT` (mempty, mempty))+    . (`runReaderT` mempty)     . getInfer  runInfer :: (forall s . InferT s (FreshIdT Int (ST s)) a) -> Either InferError a@@ -667,6 +657,7 @@   do     Judgment as cs t <- infer ex     let+      unbounds :: Set VarName       unbounds =         (Set.difference `on` Set.fromList)           (Assumption.keys as )@@ -683,30 +674,32 @@             , s       <- ss             , t       <- Assumption.lookup x as         ]-      eres = (`evalState` inferState) $ runSolver $-        do-          subst <- solve $ cs <> cs'-          pure (subst, subst `apply` t)+      evalResult =+        (`evalState` inferState) . runSolver $ second (`apply` t) . join (,) <$> solve (cs <> cs')      either       (throwError . TypeInferenceErrors)       pure-      eres+      evalResult  -- | Solve for the toplevel type of an expression in a given environment inferExpr :: Env -> NExpr -> Either InferError [Scheme] inferExpr env ex =-  (\ (subst, ty) -> closeOver $ subst `apply` ty) <<$>>-    runInfer (inferType env ex)+  closeOver . uncurry apply <<$>> runInfer (inferType env ex)  unops :: Type -> NUnaryOp -> [Constraint] unops u1 op =-  [ EqConst u1-   (case op of-      NNot -> typeFun [typeBool                   , typeBool                       ]-      NNeg -> TMany   [typeFun  [typeInt, typeInt], typeFun  [typeFloat, typeFloat]]-    )-  ]+  one $+    EqConst u1 $+      case op of+        NNot -> mkUnaryConstr typeBool+        NNeg -> TMany $ mkUnaryConstr <$> [typeInt, typeFloat]+ where+  mkUnaryConstr :: Type -> Type+  mkUnaryConstr = typeFun . mk2same+   where+    mk2same :: a -> NonEmpty a+    mk2same a = a :| one a  binops :: Type -> NBinaryOp -> [Constraint] binops u1 op =@@ -724,47 +717,55 @@   where -  gate          = eqCnst [typeBool, typeBool, typeBool]-  concatenation = eqCnst [typeList, typeList, typeList]+  mk3 :: a -> a -> a -> NonEmpty a+  mk3 a b c = a :| [b, c] -  eqCnst l = [EqConst u1 $ typeFun l]+  mk3same :: a -> NonEmpty a+  mk3same a = a :| [a, a] +  allConst :: Type -> [Constraint]+  allConst = one . EqConst u1 . typeFun . mk3same++  gate          = allConst typeBool+  concatenation = allConst typeList++  eqConstrMtx :: [NonEmpty Type] -> [Constraint]+  eqConstrMtx = one . EqConst u1 . TMany . fmap typeFun+   inequality =-    eqCnstMtx-      [ [typeInt  , typeInt  , typeBool]-      , [typeFloat, typeFloat, typeBool]-      , [typeInt  , typeFloat, typeBool]-      , [typeFloat, typeInt  , typeBool]+    eqConstrMtx+      [ mk3 typeInt   typeInt   typeBool+      , mk3 typeFloat typeFloat typeBool+      , mk3 typeInt   typeFloat typeBool+      , mk3 typeFloat typeInt   typeBool       ]    arithmetic =-    eqCnstMtx-      [ [typeInt  , typeInt  , typeInt  ]-      , [typeFloat, typeFloat, typeFloat]-      , [typeInt  , typeFloat, typeFloat]-      , [typeFloat, typeInt  , typeFloat]+    eqConstrMtx+      [ mk3same typeInt+      , mk3same typeFloat+      , mk3 typeInt   typeFloat typeFloat+      , mk3 typeFloat typeInt   typeFloat       ]    rUnion =-    eqCnstMtx-      [ [typeSet , typeSet , typeSet]-      , [typeSet , typeNull, typeSet]-      , [typeNull, typeSet , typeSet]+    eqConstrMtx+      [ mk3same typeSet+      , mk3 typeSet  typeNull typeSet+      , mk3 typeNull typeSet  typeSet       ]    addition =-    eqCnstMtx-      [ [typeInt   , typeInt   , typeInt   ]-      , [typeFloat , typeFloat , typeFloat ]-      , [typeInt   , typeFloat , typeFloat ]-      , [typeFloat , typeInt   , typeFloat ]-      , [typeString, typeString, typeString]-      , [typePath  , typePath  , typePath  ]-      , [typeString, typeString, typePath  ]+    eqConstrMtx+      [ mk3same typeInt+      , mk3same typeFloat+      , mk3 typeInt    typeFloat  typeFloat+      , mk3 typeFloat  typeInt    typeFloat+      , mk3same typeString+      , mk3same typePath+      , mk3 typeString typeString typePath       ] -  eqCnstMtx mtx = [EqConst u1 $ TMany $ typeFun <$> mtx]- liftInfer :: Monad m => m a -> InferT s m a liftInfer = InferT . lift . lift . lift @@ -773,13 +774,11 @@ infer :: MonadInfer m => NExpr -> InferT s m (Judgment s) infer = foldFix Eval.eval -inferTop :: Env -> [(Text, NExpr)] -> Either InferError Env+inferTop :: Env -> [(VarName, NExpr)] -> Either InferError Env inferTop env []                = pure env inferTop env ((name, ex) : xs) =-  either-    Left-    (\ ty -> inferTop (extend env (name, ty)) xs)-    (inferExpr env ex)+  (\ ty -> inferTop (extend env (name, ty)) xs)+    =<< inferExpr env ex  -- * Other @@ -787,13 +786,15 @@     deriving (Functor, Applicative, Alternative, Monad, MonadPlus,               MonadLogic, MonadState [TypeError]) -runSolver :: Monad m => Solver m a -> m (Either [TypeError] [a])-runSolver (Solver s) = do-  res <- runStateT (observeAllT s) mempty-  pure $-    case res of-      (x : xs, _ ) -> pure (x : xs)-      (_     , es) -> Left (ordNub es)+runSolver :: forall m a . Monad m => Solver m a -> m (Either [TypeError] [a])+runSolver (Solver s) =+  uncurry report <$> runStateT (observeAllT s) mempty+ where+  report :: [a] -> [TypeError] -> Either [TypeError] [a]+  report xs e =+    if null xs+      then Left (ordNub e)+      else pure xs  -- ** Instances @@ -827,13 +828,9 @@ -- Putting a statement that lists of different lengths containing various types would not -- be unified. unifies t1@(TList _    ) t2@(TList _    ) = throwError $ UnificationFail t1 t2-unifies (   TSet True _) (   TSet True _) = stub-unifies (TSet False b) (TSet True s)-  | M.keys b `intersect` M.keys s == M.keys s = stub-unifies (TSet True s) (TSet False b)-  | M.keys b `intersect` M.keys s == M.keys b = stub-unifies (TSet False s) (TSet False b)-  | null (M.keys b \\ M.keys s) = stub+unifies (TSet Variadic _) (TSet Variadic _)                                 = stub+unifies (TSet Closed   s) (TSet Closed   b) | null (M.keys b \\ M.keys s)   = stub+unifies (TSet _ a) (TSet _ b) | (M.keys a `intersect` M.keys b) == M.keys b = stub unifies (t1 :~> t2) (t3 :~> t4) = unifyMany [t1, t2] [t3, t4] unifies (TMany t1s) t2          = considering t1s >>- (`unifies` t2) unifies t1          (TMany t2s) = considering t2s >>- unifies t1@@ -844,17 +841,15 @@ unifyMany (t1 : ts1) (t2 : ts2) = do   su1 <- unifies t1 t2   su2 <--    unifyMany-      (apply su1 ts1)-      (apply su1 ts2)-  pure $ su2 `compose` su1+    (unifyMany `on` apply su1) ts1 ts2+  pure $ compose su1 su2 unifyMany t1 t2 = throwError $ UnificationMismatch t1 t2  nextSolvable :: [Constraint] -> (Constraint, [Constraint])-nextSolvable xs = fromJust $ find solvable $ takeFirstOnes xs+nextSolvable = fromJust . find solvable . pickFirstOne  where-  takeFirstOnes :: Eq a => [a] -> [(a, [a])]-  takeFirstOnes xs = [ (x, ys) | x <- xs, let ys = delete x xs ]+  pickFirstOne :: Eq a => [a] -> [(a, [a])]+  pickFirstOne xs = [ (x, ys) | x <- xs, let ys = delete x xs ]    solvable :: (Constraint, [Constraint]) -> Bool   solvable (EqConst{}     , _) = True@@ -862,18 +857,23 @@   solvable (ImpInstConst _t1 ms t2, cs) =     Set.null $ (ms `Set.difference` ftv t2) `Set.intersection` atv cs -solve :: MonadState InferState m => [Constraint] -> Solver m Subst+solve :: forall m . MonadState InferState m => [Constraint] -> Solver m Subst solve [] = stub solve cs = solve' $ nextSolvable cs  where-  solve' (EqConst t1 t2, cs) =-    unifies t1 t2 >>--      \su1 -> solve (apply su1 cs) >>--          \su2 -> pure $ su2 `compose` su1-   solve' (ImpInstConst t1 ms t2, cs) =     solve (ExpInstConst t1 (generalize ms t2) : cs)+  solve' (ExpInstConst t s, cs) =+    do+      s' <- lift $ instantiate s+      solve (EqConst t s' : cs)+  solve' (EqConst t1 t2, cs) =+    (\ su1 ->+      (pure . compose su1) -<< solve ((`apply` cs) su1)+    ) -<<+    unifies t1 t2 -  solve' (ExpInstConst t s, cs) = do-    s' <- lift $ instantiate s-    solve (EqConst t s' : cs)+infixr 1 -<<+-- | @LogicT@ fair conjunction, since library has only @>>-@+(-<<) :: Monad m => (a -> Solver m b) -> Solver m a -> Solver m b+(-<<) = flip (>>-)
src/Nix/Type/Type.hs view
@@ -3,11 +3,8 @@ --   Therefore -> from this the type inference follows. module Nix.Type.Type where -import           Prelude                 hiding ( Type, TVar )-import           Data.Foldable                  ( foldr1 )-import           Nix.Utils                      ( AttrSet )--type Name = Text+import           Prelude                 hiding (Type, TVar)+import           Nix.Expr.Types  -- | Hindrey-Milner type interface @@ -19,7 +16,7 @@ data Type   = TVar TVar                -- ^ Type variable in the Nix type system.   | TCon Text                -- ^ Concrete (non-polymorphic, constant) type in the Nix type system.-  | TSet Bool (AttrSet Type) -- ^ Heterogeneous map in the Nix type system. @True@ -> variadic.+  | TSet Variadic (AttrSet Type) -- ^ Heterogeneous map in the Nix type system. @True@ -> variadic.   | TList [Type]             -- ^ Heterogeneous list in the Nix type system.   | (:~>) Type Type          -- ^ Type arrow (@Type -> Type@) in the Nix type system.   | TMany [Type]             -- ^ Variant type (term). Since relating to Nix type system, more precicely -@@ -34,22 +31,21 @@ data Scheme = Forall [TVar] Type -- ^ @Forall [TVar] Type@: the Nix type system @forall vars. type@.   deriving (Show, Eq, Ord) +-- | Concrete types in the Nix type system.+typeNull, typeBool, typeInt, typeFloat, typeString, typePath :: Type+typeNull   = TCon "null"+typeBool   = TCon "boolean"+typeInt    = TCon "integer"+typeFloat  = TCon "float"+typeString = TCon "string"+typePath   = TCon "path"+ -- This models a set that unifies with any other set. typeSet :: Type-typeSet = TSet True mempty+typeSet = TSet mempty mempty  typeList :: Type typeList = TList mempty -typeFun :: [Type] -> Type--- Please, replace with safe analog to `foldr1`-typeFun = foldr1 (:~>)---- | Concrete types in the Nix type system.-typeInt, typeFloat, typeBool, typeString, typePath, typeNull :: Type-typeInt    = TCon "integer"-typeFloat  = TCon "float"-typeBool   = TCon "boolean"-typeString = TCon "string"-typePath   = TCon "path"-typeNull   = TCon "null"+typeFun :: NonEmpty Type -> Type+typeFun (head_ :| tail_) = foldr (:~>) head_ tail_
+ src/Nix/Unused.hs view
@@ -0,0 +1,82 @@+{-# language FunctionalDependencies #-}+{-# language TemplateHaskell #-}++{-# options_ghc -Wno-missing-signatures #-}++-- | This module holds unused code.+-- So, if someone wants something - look here, use it & move to appropriate place.+module Nix.Unused+ where++import           Control.Monad.Free             ( Free(..) )+import           Data.Fix                       ( Fix(..) )+import           Lens.Family2.TH                ( makeLensesBy )++-- * From "Nix.Utils"++-- | > type AlgM f m a = f a -> m a+type AlgM f m a = f a -> m a++whenFree :: (Monoid b)+  => (f (Free f a) -> b) -> Free f a -> b+whenFree =+  free+    mempty+{-# inline whenFree #-}++whenPure :: (Monoid b)+  => (a -> b) -> Free f a -> b+whenPure f =+  free+    f+    mempty+{-# inline whenPure #-}++-- | Replace:+--  @Pure a -> a@+--  @Free -> Fix@+freeToFix :: Functor f => (a -> Fix f) -> Free f a -> Fix f+freeToFix f = go+ where+  go =+    free+      f+      $ Fix . (go <$>)++-- | Replace:+--  @a -> Pure a@+--  @Fix -> Free@+fixToFree :: Functor f => Fix f -> Free f a+fixToFree = Free . go+ where+  go (Fix f) = Free . go <$> f+++loeb :: Functor f => f (f a -> a) -> f a+loeb x = go+ where+  go = ($ go) <$> x++adiM+  :: ( Traversable t+     , Monad m+     )+  => Transform t (m a)+  -> AlgM t m a+  -> Fix t+  -> m a+adiM g f = g $ f <=< traverse (adiM g f) . unFix++para :: Functor f => (f (Fix f, a) -> a) -> Fix f -> a+para f = f . fmap (id &&& para f) . unFix++paraM :: (Traversable f, Monad m) => (f (Fix f, a) -> m a) -> Fix f -> m a+paraM f = f <=< traverse (\x -> (x, ) <$> paraM f x) . unFix++cataP :: Functor f => (Fix f -> f a -> a) -> Fix f -> a+cataP f x = f x . fmap (cataP f) . unFix $ x++cataPM :: (Traversable f, Monad m) => (Fix f -> f a -> m a) -> Fix f -> m a+cataPM f x = f x <=< traverse (cataPM f) . unFix $ x++$(makeLensesBy (\n -> pure $ "_" <> n) ''Fix)
src/Nix/Utils.hs view
@@ -1,56 +1,168 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}+{-# language NoImplicitPrelude #-}+{-# language CPP #-}+{-# language GeneralizedNewtypeDeriving #-} -{-# OPTIONS_GHC -Wno-missing-signatures #-}+-- | This is a module of custom "Prelude" code.+-- It is for import for projects other then @HNix@.+-- For @HNix@ - this module gets reexported by "Prelude", so for @HNix@ please fix-up pass-through there.+module Nix.Utils+  ( KeyMap+  , TransformF+  , Transform+  , Alg -module Nix.Utils (module Nix.Utils, module X) where+  , Path(..)+  , isAbsolute+  , (</>)+  , joinPath+  , splitDirectories+  , takeDirectory+  , takeFileName+  , takeBaseName+  , takeExtension+  , takeExtensions+  , addExtension+  , dropExtensions+  , replaceExtension +  , Has(..)+  , trace+  , traceM+  , stub+  , pass+  , whenTrue+  , whenFalse+  , list+  , whenText+  , free+  , whenJust+  , dup+  , mapPair+  , both+  , readFile+  , traverseM+  , lifted+  , loebM+  , adi+  , module X+  )+ where++import           Relude                  hiding ( pass+                                                , force+                                                , readFile+                                                , whenJust+                                                , whenNothing+                                                , trace+                                                , traceM+                                                )++import           Data.Binary                    ( Binary )+import           Data.Data                      ( Data )+import           Codec.Serialise                ( Serialise ) import           Control.Monad.Fix              ( MonadFix(..) ) import           Control.Monad.Free             ( Free(..) ) import           Control.Monad.Trans.Control    ( MonadTransControl(..) ) import qualified Data.Aeson                    as A-import qualified Data.Aeson.Encoding           as A-#if MIN_VERSION_aeson(2,0,0)-import qualified Data.Aeson.KeyMap             as AKM-#else-import qualified Data.HashMap.Strict           as HM-#endif import           Data.Fix                       ( Fix(..) )-import qualified Data.HashMap.Lazy             as M import qualified Data.Text                     as Text-import qualified Data.Vector                   as V-import           Lens.Family2                  as X hiding ((&))+import qualified Data.Text.IO                 as Text+import           Lens.Family2                  as X+                                                ( view+                                                , over+                                                , LensLike'+                                                , Lens'+                                                ) import           Lens.Family2.Stock             ( _1                                                 , _2                                                 )-import           Lens.Family2.TH                ( makeLensesBy )+import qualified System.FilePath              as FilePath  #if ENABLE_TRACING-import           Debug.Trace as X+import qualified Relude.Debug                 as X #else -- Well, since it is currently CPP intermingled with Debug.Trace, required to use String here. trace :: String -> a -> a trace = const id {-# inline trace #-} traceM :: Monad m => String -> m ()-traceM = const pass+traceM = const stub {-# inline traceM #-} #endif -$(makeLensesBy (\n -> pure $ "_" <> n) ''Fix)+-- | To have explicit type boundary between FilePath & String.+newtype Path = Path FilePath+  deriving+    ( Eq, Ord, Generic+    , Typeable, Data, NFData, Serialise, Binary, A.ToJSON, A.FromJSON+    , Show, Read, Hashable+    , Semigroup, Monoid+    ) +instance ToText Path where+  toText = toText @String . coerce++instance IsString Path where+  fromString = coerce++-- This set of @Path@ funcs is to control system filepath types & typesafety and to easy migrate from FilePath to anything suitable (like @path@ or so).++-- | @isAbsolute@ specialized to @Path@.+isAbsolute :: Path -> Bool+isAbsolute = coerce FilePath.isAbsolute++-- | @(</>)@ specialized to @Path@+(</>) :: Path -> Path -> Path+(</>) = coerce (FilePath.</>)+infixr 5 </>++-- | @joinPath@ specialized to @Path@+joinPath :: [Path] -> Path+joinPath = coerce FilePath.joinPath++-- | @splitDirectories@ specialized to @Path@+splitDirectories :: Path -> [Path]+splitDirectories = coerce FilePath.splitDirectories++-- | @takeDirectory@ specialized to @Path@+takeDirectory :: Path -> Path+takeDirectory = coerce FilePath.takeDirectory++-- | @takeFileName@ specialized to @Path@+takeFileName :: Path -> Path+takeFileName = coerce FilePath.takeFileName++-- | @takeBaseName@ specialized to @Path@+takeBaseName :: Path -> String+takeBaseName = coerce FilePath.takeBaseName++-- | @takeExtension@ specialized to @Path@+takeExtension :: Path -> String+takeExtension = coerce FilePath.takeExtensions++-- | @takeExtensions@ specialized to @Path@+takeExtensions :: Path -> String+takeExtensions = coerce FilePath.takeExtensions++addExtension :: Path -> String -> Path+addExtension = coerce FilePath.addExtension++-- | @dropExtensions@ specialized to @Path@+dropExtensions :: Path -> Path+dropExtensions = coerce FilePath.dropExtensions++-- | @replaceExtension@ specialized to @Path@+replaceExtension :: Path -> String -> Path+replaceExtension = coerce FilePath.replaceExtension++ -- | > Hashmap Text -- type synonym-type AttrSet = HashMap Text+type KeyMap = HashMap Text  -- | F-algebra defines how to reduce the fixed-point of a functor to a value. -- > type Alg f a = f a -> a type Alg f a = f a -> a --- | > type AlgM f m a = f a -> m a-type AlgM f m a = f a -> m a- -- | Do according transformation. -- -- It is a transformation of a recursion scheme.@@ -63,28 +175,25 @@ -- You got me, it is a natural transformation. type TransformF f a = (f -> a) -> f -> a -loeb :: Functor f => f (f a -> a) -> f a-loeb x = go- where-  go = ($ go) <$> x+class Has a b where+  hasLens :: Lens' a b +instance Has a a where+  hasLens f = f++instance Has (a, b) a where+  hasLens = _1++instance Has (a, b) b where+  hasLens = _2+ loebM :: (MonadFix m, Traversable t) => t (t a -> m a) -> m (t a) -- Sectioning here insures optimization happening. loebM f = mfix $ \a -> (`traverse` f) ($ a) {-# inline loebM #-} -para :: Functor f => (f (Fix f, a) -> a) -> Fix f -> a-para f = f . fmap (id &&& para f) . unFix--paraM :: (Traversable f, Monad m) => (f (Fix f, a) -> m a) -> Fix f -> m a-paraM f = f <=< traverse (\x -> (x, ) <$> paraM f x) . unFix--cataP :: Functor f => (Fix f -> f a -> a) -> Fix f -> a-cataP f x = f x . fmap (cataP f) . unFix $ x--cataPM :: (Traversable f, Monad m) => (Fix f -> f a -> m a) -> Fix f -> m a-cataPM f x = f x <=< traverse (cataPM f) . unFix $ x-+--  2021-08-21: NOTE: Someone needs to put in normal words, what this does.+-- This function is pretty spefic & used only once, in "Nix.Normal". lifted   :: (MonadTransControl u, Monad (u m), Monad m)   => ((a -> m (StT u b)) -> m (StT u b))@@ -95,29 +204,12 @@     lftd <- liftWith (\run -> f (run . k))     restoreT $ pure lftd --- | Replace:---  @Pure a -> a@---  @Free -> Fix@-freeToFix :: Functor f => (a -> Fix f) -> Free f a -> Fix f-freeToFix f = go- where-  go =-    free-      f-      $ Fix . (go <$>)---- | Replace:---  @a -> Pure a@---  @Fix -> Free@-fixToFree :: Functor f => Fix f -> Free f a-fixToFree = Free . go- where-  go (Fix f) = Free . go <$> f- -- | adi is Abstracting Definitional Interpreters: -- --     https://arxiv.org/abs/1707.04755 --+--   All ADI does is interleaves every layer of evaluation by inserting intermitten layers between them, in that way the evaluation can be extended/embelished in any way wanted. Look at its use to see great examples.+-- --   Essentially, it does for evaluation what recursion schemes do for --   representation: allows threading layers through existing structure, only --   in this case through behavior.@@ -129,72 +221,7 @@   -> a adi g f = g $ f . (adi g f <$>) . unFix -adiM-  :: ( Traversable t-     , Monad m-     )-  => Transform t (m a)-  -> AlgM t m a-  -> Fix t-  -> m a-adiM g f = g $ f <=< traverse (adiM g f) . unFix --class Has a b where-  hasLens :: Lens' a b--instance Has a a where-  hasLens f = f--instance Has (a, b) a where-  hasLens = _1--instance Has (a, b) b where-  hasLens = _2--toEncodingSorted :: A.Value -> A.Encoding-toEncodingSorted = \case-  A.Object m ->-    A.pairs-      . mconcat-      . ((\(k, v) -> A.pair k $ toEncodingSorted v) <$>)-      . sortWith fst $-#if MIN_VERSION_aeson(2,0,0)-          AKM.toList-#else-          HM.toList-#endif-          m-  A.Array l -> A.list toEncodingSorted $ V.toList l-  v         -> A.toEncoding v--data NixPathEntryType = PathEntryPath | PathEntryURI deriving (Show, Eq)---- | @NIX_PATH@ is colon-separated, but can also contain URLs, which have a colon--- (i.e. @https://...@)-uriAwareSplit :: Text -> [(Text, NixPathEntryType)]-uriAwareSplit txt =-  case Text.break (== ':') txt of-    (e1, e2)-      | Text.null e2                              -> [(e1, PathEntryPath)]-      | "://" `Text.isPrefixOf` e2      ->-        let ((suffix, _) : path) = uriAwareSplit (Text.drop 3 e2) in-        (e1 <> "://" <> suffix, PathEntryURI) : path-      | otherwise                                 -> (e1, PathEntryPath) : uriAwareSplit (Text.drop 1 e2)--alterF-  :: (Eq k, Hashable k, Functor f)-  => (Maybe v -> f (Maybe v))-  -> k-  -> HashMap k v-  -> f (HashMap k v)-alterF f k m =-  maybe-    (M.delete k m)-    (\ v -> M.insert k v m)-    <$> f (M.lookup k m)-- -- | Analog for @bool@ or @maybe@, for list-like cons structures. list   :: Foldable t@@ -206,6 +233,14 @@     (null l) {-# inline list #-} +whenText+  :: a -> (Text -> a) -> Text -> a+whenText e f t =+  bool+    (f t)+    e+    (Text.null t)+ -- | Lambda analog of @maybe@ or @either@ for Free monad. free :: (a -> b) -> (f (Free f a) -> b) -> Free f a -> b free fP fF fr =@@ -230,20 +265,15 @@     mempty {-# inline whenFalse #-} -whenFree :: (Monoid b)-  => (f (Free f a) -> b) -> Free f a -> b-whenFree =-  free-    mempty-{-# inline whenFree #-}--whenPure :: (Monoid b)-  => (a -> b) -> Free f a -> b-whenPure f =-  free-    f+whenJust+  :: Monoid b+  => (a -> b)+  -> Maybe a+  -> b+whenJust =+  maybe     mempty-{-# inline whenPure #-}+{-# inline whenJust #-}   -- | Apply a single function to both components of a pair.@@ -271,3 +301,23 @@ stub :: (Applicative f, Monoid a) => f a stub = pure mempty {-# inline stub #-}++-- | Alias for @stub@, since @Relude@ has more specialized @pure ()@.+pass :: (Applicative f) => f ()+pass = stub+{-# inline pass #-}++readFile :: Path -> IO Text+readFile = Text.readFile . coerce++traverseM+  :: ( Applicative m+     , Applicative f+     , Traversable t+     )+  => ( a+     -> m (f b)+     )+  -> t a+  -> m (f (t b))+traverseM f x = sequenceA <$> traverse f x
src/Nix/Utils/Fix1.hs view
@@ -1,9 +1,9 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE CPP #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE PolyKinds #-}-{-# LANGUAGE UndecidableInstances #-}+{-# language TypeFamilies #-}+{-# language ConstraintKinds #-}+{-# language CPP #-}+{-# language GeneralizedNewtypeDeriving #-}+{-# language PolyKinds #-}+{-# language UndecidableInstances #-}  module Nix.Utils.Fix1 where @@ -87,8 +87,11 @@   type Ref (Fix1T t m) = Ref m    newRef  = lift . newRef+  {-# inline newRef #-}   readRef = lift . readRef+  {-# inline readRef #-}   writeRef r = lift . writeRef r+  {-# inline writeRef #-}   instance@@ -98,6 +101,7 @@   => MonadAtomicRef (Fix1T t m)  where   atomicModifyRef r = lift . atomicModifyRef r+  {-# inline atomicModifyRef #-}  {- 
src/Nix/Value.hs view
@@ -1,22 +1,18 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE ViewPatterns #-}+{-# language CPP #-}+{-# language DeriveAnyClass #-}+{-# language KindSignatures #-}+{-# language ConstraintKinds #-}+{-# language PatternSynonyms #-}+{-# language RankNTypes #-}+{-# language TemplateHaskell #-} -{-# OPTIONS_GHC -Wno-missing-signatures #-}-{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}+{-# options_ghc -Wno-missing-signatures #-}+{-# options_ghc -Wno-missing-pattern-synonym-signatures #-}  -- | The core of the type system, Nix language values module Nix.Value where -import           Prelude                 hiding ( force )-import           Nix.Utils import           Control.Comonad                ( Comonad                                                 , extract                                                 )@@ -36,13 +32,12 @@                                                 , showString                                                 , showParen                                                 )-import           Lens.Family2.Stock             ( _1 )+import           Lens.Family2.Stock             ( _2 ) import           Lens.Family2.TH                ( makeTraversals                                                 , makeLenses                                                 ) import           Nix.Atoms import           Nix.Expr.Types-import           Nix.Expr.Types.Annotated import           Nix.String import           Nix.Thunk @@ -118,14 +113,13 @@      -- | A string has a value and a context, which can be used to record what a      -- string has been build from     | NVStrF NixString-    | NVPathF FilePath+    | NVPathF Path     | NVListF [r]-    --  2021-05-22: NOTE: Please flip this and dependent functions.-    -- Quite frequently actions/processing happens with values-    -- (for example - forcing of values & recreation of the monad),-    -- but SourcePos does not change then-    -- That would be good to flip all 'AttrSet.* AttrSet SourcePos'-    | NVSetF (AttrSet r) (AttrSet SourcePos)+    | NVSetF PositionSet (AttrSet r)+      -- ^+      --   Quite frequently actions/processing happens with values+      --   (for example - forcing of values & recreation of the monad),+      --   but @SourcePos@ does not change then.     | NVClosureF (Params ()) (p -> m r)       -- ^ A function is a closed set of parameters representing the "call       --   signature", used at application time to check the type of arguments@@ -138,7 +132,7 @@       --   Note that 'm r' is being used here because effectively a function       --   and its set of default arguments is "never fully evaluated". This       --   enforces in the type that it must be re-evaluated for each call.-    | NVBuiltinF Text (p -> m r)+    | NVBuiltinF VarName (p -> m r)       -- ^ A builtin function is itself already in normal form. Also, it may       --   or may not choose to evaluate its argument in the production of a       --   result.@@ -151,8 +145,8 @@   liftEq _  (NVConstantF x) (NVConstantF y) = x == y   liftEq _  (NVStrF      x) (NVStrF      y) = x == y   liftEq eq (NVListF     x) (NVListF     y) = liftEq eq x y-  liftEq eq (NVSetF x _   ) (NVSetF y _   ) = liftEq eq x y-  liftEq _  (NVPathF x    ) (NVPathF y    ) = x == y+  liftEq eq (NVSetF  _   x) (NVSetF _    y) = liftEq eq x y+  liftEq _  (NVPathF     x) (NVPathF     y) = x == y   liftEq _  _               _               = False  @@ -166,7 +160,7 @@       (NVConstantF atom     ) -> showsCon1 "NVConstant" atom       (NVStrF      ns       ) -> showsCon1 "NVStr"      (stringIgnoreContext ns)       (NVListF     lst      ) -> showsCon1 "NVList"     lst-      (NVSetF      attrs  _ ) -> showsCon1 "NVSet"      attrs+      (NVSetF      _   attrs) -> showsCon1 "NVSet"      attrs       (NVClosureF  params _ ) -> showsCon1 "NVClosure"  params       (NVPathF     path     ) -> showsCon1 "NVPath"     path       (NVBuiltinF  name   _ ) -> showsCon1 "NVBuiltin"  name@@ -185,7 +179,7 @@     NVStrF      _  -> mempty     NVPathF     _  -> mempty     NVListF     l  -> foldMap f l-    NVSetF     s _ -> foldMap f s+    NVSetF     _ s -> foldMap f s     NVClosureF _ _ -> mempty     NVBuiltinF _ _ -> mempty @@ -203,11 +197,7 @@   NVStrF      s  -> pure $ NVStrF s   NVPathF     p  -> pure $ NVPathF p   NVListF     l  -> NVListF <$> sequenceA l-  NVSetF     s p ->-    liftA2-      NVSetF-      (sequenceA s)-      (pure p)+  NVSetF     p s -> NVSetF p <$> sequenceA s   NVClosureF p g -> pure $ NVClosureF p (transform <=< g)   NVBuiltinF s g -> pure $ NVBuiltinF s (transform <=< g) @@ -226,11 +216,7 @@   NVStrF      s  -> pure $ NVStrF s   NVPathF     p  -> pure $ NVPathF p   NVListF     l  -> NVListF <$> traverse f l-  NVSetF     s p ->-    liftA2-      NVSetF-      (traverse f s)-      (pure p)+  NVSetF     p s -> NVSetF p <$> traverse f s   NVClosureF p g -> pure $ NVClosureF p (transform . f <=< g)   NVBuiltinF s g -> pure $ NVBuiltinF s (transform . f <=< g) @@ -268,13 +254,13 @@     --   , NVStrF s     --   , NVPathF p     --   , NVListF l-    --   , NVSetF s p+    --   , NVSetF p s     --   ]     NVConstantF a  -> NVConstantF a     NVStrF      s  -> NVStrF s     NVPathF     p  -> NVPathF p     NVListF     l  -> NVListF l-    NVSetF     s p -> NVSetF s p+    NVSetF     p s -> NVSetF p s     NVBuiltinF s g -> NVBuiltinF s (lft . g)     NVClosureF p g -> NVClosureF p (lft . g) {-# inline hoistNValueF #-}@@ -303,7 +289,7 @@     NVStr' ns ->       showsUnaryWith showsPrec "NVStrF" p (stringIgnoreContext ns)     NVList' lst       -> showsUnaryWith (liftShowsPrec sp sl) "NVListF" p lst-    NVSet' attrs _    -> showsUnaryWith (liftShowsPrec sp sl) "NVSetF" p attrs+    NVSet'  _   attrs -> showsUnaryWith (liftShowsPrec sp sl) "NVSetF" p attrs     NVPath' path      -> showsUnaryWith showsPrec "NVPathF" p path     NVClosure' c    _ -> showsUnaryWith showsPrec "NVClosureF" p c     NVBuiltin' name _ -> showsUnaryWith showsPrec "NVBuiltinF" p name@@ -330,7 +316,7 @@   NVStrF      s  -> NVStrF s   NVPathF     p  -> NVPathF p   NVListF     l  -> NVListF l-  NVSetF     s p -> NVSetF s p+  NVSetF     p s -> NVSetF p s   NVClosureF p g -> NVClosureF p (g . f)   NVBuiltinF s g -> NVBuiltinF s (g . f) @@ -429,11 +415,11 @@ nvStr' = NValue' . pure . NVStrF  --- | Haskell @FilePath@ to the Nix path,+-- | Haskell @Path@ to the Nix path, nvPath' :: Applicative f-  => FilePath+  => Path   -> NValue' t f m r-nvPath' = NValue' . pure . NVPathF+nvPath' = NValue' . pure . NVPathF . coerce   -- | Haskell @[]@ to the Nix @[]@,@@ -445,10 +431,11 @@  -- | Haskell key-value to the Nix key-value, nvSet' :: Applicative f-  => AttrSet SourcePos+  => PositionSet   -> AttrSet r   -> NValue' t f m r-nvSet' x s = NValue' $ pure $ NVSetF s x+--  2021-07-16: NOTE: that the arguments are flipped.+nvSet' p s = NValue' $ pure $ NVSetF p s   -- | Haskell closure to the Nix closure,@@ -463,7 +450,7 @@  -- | Haskell functions to the Nix functions! nvBuiltin' :: (Applicative f, Functor m)-  => Text+  => VarName   -> (NValue t f m -> m r)   -> NValue' t f m r nvBuiltin' name f = NValue' $ pure $ NVBuiltinF name f@@ -485,10 +472,10 @@ pattern NVStr' ns <- NValue' (extract -> NVStrF ns) pattern NVPath' x <- NValue' (extract -> NVPathF x) pattern NVList' l <- NValue' (extract -> NVListF l)-pattern NVSet' s x <- NValue' (extract -> NVSetF s x)+pattern NVSet' p s <- NValue' (extract -> NVSetF p s) pattern NVClosure' x f <- NValue' (extract -> NVClosureF x f) pattern NVBuiltin' name f <- NValue' (extract -> NVBuiltinF name f)-{-# COMPLETE NVConstant', NVStr', NVPath', NVList', NVSet', NVClosure', NVBuiltin' #-}+{-# complete NVConstant', NVStr', NVPath', NVList', NVSet', NVClosure', NVBuiltin' #-}   -- * @__NValue__@: Nix language values@@ -610,12 +597,12 @@ nvStrWithoutContext :: Applicative f   => Text   -> NValue t f m-nvStrWithoutContext = nvStr . makeNixStringWithoutContext+nvStrWithoutContext = nvStr . mkNixStringWithoutContext   -- | Life of a Haskell FilePath to the life of a Nix path nvPath :: Applicative f-  => FilePath+  => Path   -> NValue t f m nvPath = Free . nvPath' @@ -627,11 +614,10 @@   nvSet :: Applicative f-  => AttrSet SourcePos+  => PositionSet   -> AttrSet (NValue t f m)   -> NValue t f m-nvSet x s = Free $ nvSet' x s-+nvSet p s = Free $ nvSet' p s  nvClosure :: (Applicative f, Functor m)   => Params ()@@ -643,7 +629,7 @@   nvBuiltin :: (Applicative f, Functor m)-  => Text+  => VarName   -> (NValue t f m     -> m (NValue t f m)     )@@ -654,7 +640,7 @@ builtin   :: forall m f t    . (MonadThunk t m (NValue t f m), MonadDataContext f m)-  => Text+  => VarName   -> ( NValue t f m     -> m (NValue t f m)     )@@ -664,7 +650,7 @@  builtin2   :: (MonadThunk t m (NValue t f m), MonadDataContext f m)-  => Text+  => VarName   -> ( NValue t f m     -> NValue t f m     -> m (NValue t f m)@@ -675,7 +661,7 @@  builtin3   :: (MonadThunk t m (NValue t f m), MonadDataContext f m)-  => Text+  => VarName   -> ( NValue t f m     -> NValue t f m     -> NValue t f m@@ -689,7 +675,7 @@  pattern NVThunk t <- Pure t pattern NVValue v <- Free v-{-# COMPLETE NVThunk, NVValue #-}+{-# complete NVThunk, NVValue #-} pattern NVConstant x <- Free (NVConstant' x) pattern NVStr ns <- Free (NVStr' ns) pattern NVPath x <- Free (NVPath' x)@@ -697,29 +683,37 @@ pattern NVSet s x <- Free (NVSet' s x) pattern NVClosure x f <- Free (NVClosure' x f) pattern NVBuiltin name f <- Free (NVBuiltin' name f)-{-# COMPLETE NVThunk, NVConstant, NVStr, NVPath, NVList, NVSet, NVClosure, NVBuiltin #-}+{-# complete NVThunk, NVConstant, NVStr, NVPath, NVList, NVSet, NVClosure, NVBuiltin #-}    -- * @TStringContext@  data TStringContext = NoContext | HasContext-  deriving Show+ deriving Show +instance Semigroup TStringContext where+  (<>) NoContext NoContext = NoContext+  (<>) _         _         = HasContext+++instance Monoid TStringContext where+  mempty = NoContext+ -- * @ValueType@  data ValueType-    = TInt-    | TFloat-    | TBool-    | TNull-    | TString TStringContext-    | TList-    | TSet-    | TClosure-    | TPath-    | TBuiltin-    deriving Show+  = TInt+  | TFloat+  | TBool+  | TNull+  | TString TStringContext+  | TList+  | TSet+  | TClosure+  | TPath+  | TBuiltin+ deriving Show   -- | Determine type of a value@@ -728,17 +722,14 @@   \case     NVConstantF a ->       case a of-        NURI   _ -> TString NoContext+        NURI   _ -> TString mempty         NInt   _ -> TInt         NFloat _ -> TFloat         NBool  _ -> TBool         NNull    -> TNull     NVStrF ns  ->       TString $-        bool-          NoContext-          HasContext-          (stringHasContext ns)+        HasContext `whenTrue` stringHasContext ns     NVListF{}    -> TList     NVSetF{}     -> TSet     NVClosureF{} -> TClosure@@ -754,8 +745,8 @@     TFloat             -> "a float"     TBool              -> "a boolean"     TNull              -> "a null"-    TString NoContext  -> "a string"-    TString HasContext -> "a string with context"+    TString NoContext  -> "a string with no context"+    TString HasContext -> "a string"     TList              -> "a list"     TSet               -> "an attr set"     TClosure           -> "a function"@@ -822,4 +813,4 @@   :: (Traversable f, Applicative g)   => VarName   -> LensLike' g (NValue' t f m a) (Maybe a)-key k = nValue . traverse . _NVSetF . _1 . hashAt k+key k = nValue . traverse . _NVSetF . _2 . hashAt k
src/Nix/Value/Equal.hs view
@@ -1,17 +1,12 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE ViewPatterns #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-}+{-# language TypeFamilies #-} -{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}+{-# options_ghc -Wno-missing-pattern-synonym-signatures #-}  module Nix.Value.Equal where -import           Prelude                 hiding ( Comparison-                                                , force-                                                )-import           Nix.Utils+import           Prelude                 hiding ( Comparison ) import           Control.Comonad                ( Comonad(extract)) import           Control.Monad.Free             ( Free(Pure,Free) ) import           Control.Monad.Trans.Except     ( throwE )@@ -25,6 +20,7 @@ import           Nix.String import           Nix.Thunk import           Nix.Value+import           Nix.Expr.Types                 ( AttrSet )  checkComparable   :: ( Framed e m@@ -35,12 +31,12 @@   -> m () checkComparable x y =   case (x, y) of-    (NVConstant (NFloat _), NVConstant (NInt   _)) -> pass-    (NVConstant (NInt   _), NVConstant (NFloat _)) -> pass-    (NVConstant (NInt   _), NVConstant (NInt   _)) -> pass-    (NVConstant (NFloat _), NVConstant (NFloat _)) -> pass-    (NVStr       _        , NVStr       _        ) -> pass-    (NVPath      _        , NVPath      _        ) -> pass+    (NVConstant (NFloat _), NVConstant (NInt   _)) -> stub+    (NVConstant (NInt   _), NVConstant (NFloat _)) -> stub+    (NVConstant (NInt   _), NVConstant (NInt   _)) -> stub+    (NVConstant (NFloat _), NVConstant (NFloat _)) -> stub+    (NVStr       _        , NVStr       _        ) -> stub+    (NVPath      _        , NVPath      _        ) -> stub     _                                              -> throwError $ Comparison x y  -- | Checks whether two containers are equal, using the given item equality@@ -79,15 +75,16 @@ isDerivationM f m =   maybe     (pure False)-    (\ t ->-      maybe-        -- We should probably really make sure the context is empty here-        -- but the C++ implementation ignores it.-        False-        ((==) "derivation" . stringIgnoreContext)-        <$> f t-    )+    p     (HashMap.Lazy.lookup "type" m)+ where+  p t =+    maybe+      -- We should probably really make sure the context is empty here+      -- but the C++ implementation ignores it.+      False+      ((==) "derivation" . stringIgnoreContext)+      <$> f t  isDerivation   :: Monad m@@ -119,7 +116,7 @@       (NVConstantF lc        , NVConstantF rc        ) -> pure $            lc == rc       (NVStrF      ls        , NVStrF      rs        ) -> pure $  (\ i -> i ls == i rs) stringIgnoreContext       (NVListF     ls        , NVListF     rs        ) ->          alignEqM eq ls rs-      (NVSetF      lm _      , NVSetF      rm _      ) ->          attrsEq lm rm+      (NVSetF      _      lm , NVSetF      _      rm ) ->          attrsEq lm rm       (NVPathF     lp        , NVPathF     rp        ) ->             pure $ lp == rp       _                                                -> pure False 
src/Nix/Var.hs view
@@ -1,9 +1,8 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# language AllowAmbiguousTypes #-}+{-# language ConstraintKinds #-} -{-# OPTIONS_GHC -Wno-orphans #-}-{-# OPTIONS_GHC -Wno-unused-top-binds #-}+{-# options_ghc -Wno-orphans #-}+{-# options_ghc -Wno-unused-top-binds #-}  module Nix.Var () where
src/Nix/XML.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE ScopedTypeVariables #-}  module Nix.XML   ( toXML )@@ -21,13 +20,14 @@  where   cyc = pure $ mkEVal "string" "<expr>" +  pp :: Element -> Text   pp e =     heading-    <> toText+    <> fromString         (ppElement $           mkE             "expr"-            [Elem e]+            (one $ Elem e)         )     <> "\n"    where@@ -38,80 +38,73 @@     NVConstant' a ->       pure $         case a of-          NURI   t -> mkEVal "string" $ toString t+          NURI   t -> mkEVal "string" t           NInt   n -> mkEVal "int"    $ show n           NFloat f -> mkEVal "float"  $ show f           NBool  b -> mkEVal "bool"   $ if b then "true" else "false"           NNull    -> mkE    "null"     mempty      NVStr' str ->-      mkEVal "string" . toString <$> extractNixString str+      mkEVal "string" <$> extractNixString str     NVList' l ->-      do-        els <- sequence l-        pure $-          mkE-            "list"-            (Elem <$> els)+      mkE "list" . fmap Elem <$> sequenceA l -    NVSet' s _ ->-      do-        kvs <- sequence s-        pure $-          mkE-            "attrs"-            ((\ (k, v) ->-                Elem $-                  Element-                    (unqual "attr")-                    [Attr (unqual "name") (toString k)]-                    [Elem v]-                    Nothing-              ) <$>-                sortWith fst (M.toList kvs)-            )+    NVSet' _ s ->+      mkE+        "attrs"+        . fmap+            mkElem'+            . sortWith fst . M.toList+        <$> sequenceA s+     where+      mkElem' :: (VarName, Element) -> Content+      mkElem' (k, v) =+        Elem $+          Element+            (unqual "attr")+            (one $ Attr (unqual "name") $ toString k)+            (one $ Elem v)+            Nothing      NVClosure' p _ ->       pure $         mkE           "function"           (paramsXML p)-    NVPath' fp        -> pure $ mkEVal "path" fp-    NVBuiltin' name _ -> pure $ mkEName "function" $ toString name+    NVPath' fp        -> pure $ mkEVal "path" $ fromString $ coerce fp+    NVBuiltin' name _ -> pure $ mkEName "function" name -mkE :: String -> [Content] -> Element-mkE n c =+mkE :: Text -> [Content] -> Element+mkE (toString -> n) c =   Element     (unqual n)     mempty     c     Nothing -mkElem :: String -> String -> String -> Element-mkElem n a v =+mkElem :: Text -> Text -> Text -> Element+mkElem (toString -> n) (toString -> a) (toString -> v) =   Element     (unqual n)-    [Attr (unqual a) v]+    (one $ Attr (unqual a) v)     mempty     Nothing -mkEVal :: String -> String -> Element+mkEVal :: Text -> Text -> Element mkEVal = (`mkElem` "value") -mkEName :: String -> String -> Element-mkEName = (`mkElem` "name")+mkEName :: Text -> VarName -> Element+mkEName x (coerce -> y) = (`mkElem` "name") x y  paramsXML :: Params r -> [Content]-paramsXML (Param name) = [Elem $ mkEName "varpat" (toString name)]-paramsXML (ParamSet s b mname) =-  [Elem $ Element (unqual "attrspat") (battr <> nattr) (paramSetXML s) Nothing]+paramsXML (Param name) = one $ Elem $ mkEName "varpat" name+paramsXML (ParamSet mname variadic pset) =+  one $ Elem $ Element (unqual "attrspat") (battr <> nattr) (paramSetXML pset) Nothing  where-  battr = [ Attr (unqual "ellipsis") "1" | b ]+  battr =+    one (Attr (unqual "ellipsis") "1") `whenTrue` (variadic == Variadic)   nattr =-    maybe-      mempty-      ((: mempty) . Attr (unqual "name") . toString)-      mname+    (one . Attr (unqual "name") . toString) `whenJust` mname  paramSetXML :: ParamSet r -> [Content]-paramSetXML = fmap (\(k, _) -> Elem $ mkEName "attr" (toString k))+paramSetXML = fmap (Elem . mkEName "attr" . fst)
+ src/Prelude.hs view
@@ -0,0 +1,20 @@+-- | This is a @Prelude@, but, please, do not put things in here,+-- put them into "Nix.Utils". This module is a pass-through-multiplexer,+-- between our custom code ("Nix.Utils") that shadows over the outside prelude that is in use ("Relude")+-- "Prelude" module has a problem of being imported & used by other projects.+-- "Nix.Utils" as a module with a regular name does not have that problem.+module Prelude+    ( module Nix.Utils+    , module Relude+    ) where++import           Nix.Utils+import           Relude                  hiding ( pass+                                                , force+                                                , readFile+                                                , whenJust+                                                , whenNothing+                                                , trace+                                                , traceM+                                                )+
tests/EvalTests.hs view
@@ -1,13 +1,11 @@-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-} -{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# options_ghc -Wno-missing-signatures #-}   module EvalTests (tests, genEvalCompareTests) where -import           Prelude hiding (lookupEnv) import           Control.Monad.Catch import           Data.List ((\\)) import qualified Data.Set as S@@ -17,136 +15,189 @@ import           Nix.Standard import           Nix.TH import           Nix.Value.Equal-import           Nix.Utils import qualified System.Directory as D-import           System.Environment (lookupEnv)-import           System.FilePath import           Test.Tasty import           Test.Tasty.HUnit import           Test.Tasty.TH import           TestCommon  case_basic_sum =-    constantEqualText "2" "1 + 1"+  constantEqualText+    "2"+    "1 + 1"  case_basic_div =-    constantEqualText "3" "builtins.div 6 2"+  constantEqualText+    "3"+    "builtins.div 6 2" -case_zero_div = do-  assertNixEvalThrows "builtins.div 1 0"-  assertNixEvalThrows "builtins.div 1.0 0"-  assertNixEvalThrows "builtins.div 1 0.0"-  assertNixEvalThrows "builtins.div 1.0 0.0"+case_zero_div =+  traverse_ assertNixEvalThrows+    [ "builtins.div 1 0"+    , "builtins.div 1.0 0"+    , "builtins.div 1 0.0"+    , "builtins.div 1.0 0.0"+    ] -case_bit_ops = do-    -- mic92 (2018-08-20): change to constantEqualText,-    -- when hnix's nix fork supports bitAnd/bitOr/bitXor-    constantEqualText' "0" "builtins.bitAnd 1 0"-    constantEqualText' "1" "builtins.bitOr 1 1"-    constantEqualText' "3" "builtins.bitXor 1 2"+case_bit_ops =+  traverse_ (uncurry constantEqualText)+    [ ("0", "builtins.bitAnd 1 0")+    , ("1", "builtins.bitOr 1 1")+    , ("3", "builtins.bitXor 1 2")+    ]  case_basic_function =-    constantEqualText "2" "(a: a) 2"+  constantEqualText+    "2"+    "(a: a) 2"  case_set_attr =-    constantEqualText "2" "{ a = 2; }.a"+  constantEqualText+    "2"+    "{ a = 2; }.a"  case_function_set_arg =-    constantEqualText "2" "({ a }: 2) { a = 1; }"+  constantEqualText+    "2"+    "({ a }: 2) { a = 1; }"  case_function_set_two_arg =-    constantEqualText "2" "({ a, b ? 3 }: b - a) { a = 1; }"+  constantEqualText+    "2"+    "({ a, b ? 3 }: b - a) { a = 1; }"  case_function_set_two_arg_default_scope =-    constantEqualText "2" "({ x ? 1, y ? x * 3 }: y - x) {}"+  constantEqualText+    "2"+    "({ x ? 1, y ? x * 3 }: y - x) {}"  case_function_default_env =-    constantEqualText "2" "let default = 2; in ({ a ? default }: a) {}"+  constantEqualText+    "2"+    "let default = 2; in ({ a ? default }: a) {}"  case_function_definition_uses_environment =-    constantEqualText "3" "let f = (let a=1; in x: x+a); in f 2"+  constantEqualText+    "3"+    "let f = (let a=1; in x: x+a); in f 2"  case_function_atpattern =-    -- jww (2018-05-09): This should be constantEqualText-    constantEqualText' "2" "(({a}@attrs:attrs) {a=2;}).a"+  -- jww (2018-05-09): This should be constantEqualText+  constantEqualText'+    "2"+    "(({a}@attrs:attrs) {a=2;}).a"  case_function_ellipsis =-    -- jww (2018-05-09): This should be constantEqualText-    constantEqualText' "2" "(({a, ...}@attrs:attrs) {a=0; b=2;}).b"+  -- jww (2018-05-09): This should be constantEqualText+  constantEqualText'+    "2"+    "(({a, ...}@attrs:attrs) {a=0; b=2;}).b"  case_function_default_value_not_in_atpattern =-    constantEqualText "false" "({a ? 2}@attrs: attrs ? a) {}"+  constantEqualText+    "false"+    "({a ? 2}@attrs: attrs ? a) {}"  case_function_arg_shadowing =-    constantEqualText "6" "(y: y: x: x: x + y) 1 2 3 4"+  constantEqualText+    "6"+    "(y: y: x: x: x + y) 1 2 3 4"  case_function_recursive_args =-    constantEqualText "2" "({ x ? 1, y ? x * 3}: y - x) {}"+  constantEqualText+    "2"+    "({ x ? 1, y ? x * 3}: y - x) {}"  case_function_recursive_sets =-    constantEqualText "[ [ 6 4 100 ] 4 ]" [text|-        let x = rec {+  constantEqualText+    "[ [ 6 4 100 ] 4 ]"+    [text|+      let x = rec { -          y = 2;-          z = { w = 4; };-          v = rec {-            u = 6;-            t = [ u z.w s ];-          };+        y = 2;+        z = { w = 4; };+        v = rec {+          u = 6;+          t = [ u z.w s ];+        }; -        }; s = 100; in [ x.v.t x.z.w ]+      }; s = 100; in [ x.v.t x.z.w ]     |]  case_nested_with =-    constantEqualText "2" "with { x = 1; }; with { x = 2; }; x"+  constantEqualText+    "2"+    "with { x = 1; }; with { x = 2; }; x"  case_with_strictness =-    constantEqualText "5" "let x = with x; with { a = 5; }; a; in x"+  constantEqualText+    "5"+    "let x = with x; with { a = 5; }; a; in x"  case_match_failure_null =-    constantEqualText "null" "builtins.match \"ab\" \"abc\""+  constantEqualText+    "null"+    "builtins.match \"ab\" \"abc\""  case_find_file_success_no_prefix =-    constantEqualText "./tests/files/findFile.nix"-                      "builtins.findFile [{ path=\"./tests/files\"; prefix=\"\"; }] \"findFile.nix\""+  constantEqualText+    "./tests/files/findFile.nix"+    "builtins.findFile [{ path=\"./tests/files\"; prefix=\"\"; }] \"findFile.nix\""  case_find_file_success_with_prefix =-    constantEqualText "./tests/files/findFile.nix"-                      "builtins.findFile [{ path=\"./tests/files\"; prefix=\"nix\"; }] \"nix/findFile.nix\""+  constantEqualText+    "./tests/files/findFile.nix"+    "builtins.findFile [{ path=\"./tests/files\"; prefix=\"nix\"; }] \"nix/findFile.nix\""  case_find_file_success_folder =-    constantEqualText "./tests/files"-                      "builtins.findFile [{ path=\"./tests\"; prefix=\"\"; }] \"files\""+  constantEqualText+    "./tests/files"+    "builtins.findFile [{ path=\"./tests\"; prefix=\"\"; }] \"files\""  case_find_file_failure_not_found =-    assertNixEvalThrows "builtins.findFile [{ path=\"./tests/files\"; prefix=\"\"; }] \"not_found.nix\""+  assertNixEvalThrows+    "builtins.findFile [{ path=\"./tests/files\"; prefix=\"\"; }] \"not_found.nix\""  case_find_file_failure_invalid_arg_1 =-    assertNixEvalThrows "builtins.findFile 1 \"files\""+  assertNixEvalThrows+    "builtins.findFile 1 \"files\""  case_find_file_failure_invalid_arg_2 =-    assertNixEvalThrows "builtins.findFile [{ path=\"./tests/files\"; prefix=\"\"; }] 2"+  assertNixEvalThrows+    "builtins.findFile [{ path=\"./tests/files\"; prefix=\"\"; }] 2"  case_find_file_failure_invalid_arg_no_path =-    assertNixEvalThrows "builtins.findFile [{ prefix=\"\"; }] \"files\""+  assertNixEvalThrows+    "builtins.findFile [{ prefix=\"\"; }] \"files\""  case_infinite_recursion =-    assertNixEvalThrows "let foo = a: bar a; bar = a: foo a; in foo 3"+  assertNixEvalThrows+    "let foo = a: bar a; bar = a: foo a; in foo 3"  case_nested_let =-    constantEqualText "3" "let a = 3; x.x = 2; in a"+  constantEqualText+    "3"+    "let a = 3; x.x = 2; in a"  case_nested_nested_let =-    constantEqualText "3" "let a = 3; x.x = let b = a; in b; c = x.x; in c"+  constantEqualText+    "3"+    "let a = 3; x.x = let b = a; in b; c = x.x; in c"  case_inherit_in_rec_set =-    constantEqualText "1" "let x = 1; in (rec { inherit x; }).x"+  constantEqualText+    "1"+    "let x = 1; in (rec { inherit x; }).x"  case_lang_version =-    constantEqualText "5" "builtins.langVersion"+  constantEqualText+    "5"+    "builtins.langVersion"  case_rec_set_attr_path_simpl =-    constantEqualText "123" [text|+  constantEqualText+    "123"+    [text|       let x = rec {         foo.number = 123;         foo.function = y: foo.number;@@ -154,7 +205,9 @@     |]  case_inherit_from_set_has_no_scope =-    constantEqualText' "false" [text|+  constantEqualText'+    "false"+    [text|       (builtins.tryEval (         let x = 1;             y = { z = 2; };@@ -163,7 +216,7 @@     |]  -- github/orblivion (2018-08-05): Adding these failing tests so we fix this feature-+-- -- case_overrides = --     constantEqualText' "2" [text| --       let@@ -190,171 +243,198 @@ --       }.__overrides.a) --     |] -case_unsafegetattrpos1 =-    constantEqualText "[ 5 14 ]" [text|-      let e = 1;-          f = 1;-          t = {};-          s = {-            inherit t e f;-            a = 1;-            "b" = 2;-            c.d = 3;-          };-          p = builtins.unsafeGetAttrPos "e" s; in-      [ p.line p.column ]-    |]+case_unsafegetattrpos =+  traverse_ (uncurry constantEqualText)+    [ ( "[ 5 14 ]"+      , [text|+          let e = 1;+              f = 1;+              t = {};+              s = {+                inherit t e f;+                a = 1;+                "b" = 2;+                c.d = 3;+              };+              p = builtins.unsafeGetAttrPos "e" s; in+          [ p.line p.column ]+          |]+      )+    , ( "[ 5 14 ]"+      , [text|+          let e = 1;+              f = 1;+              t = {};+              s = {+                inherit t e f;+                a = 1;+                "b" = 2;+                c.d = 3;+              };+              p = builtins.unsafeGetAttrPos "f" s; in+          [ p.line p.column ]+        |]+      )+    , ( "[ 6 7 ]"+      , [text|+          let e = 1;+              f = 1;+              t = {};+              s = {+                inherit t e f;+                a = 1;+                "b" = 2;+                c.d = 3;+              };+              p = builtins.unsafeGetAttrPos "a" s; in+            [ p.line p.column ]+          |]+      )+    , ( "[ 7 7 ]"+      , [text|+        let e = 1;+            f = 1;+            t = {};+            s = {+              inherit t e f;+              a = 1;+              "b" = 2;+              c.d = 3;+            };+            p = builtins.unsafeGetAttrPos "b" s; in+          [ p.line p.column ]+        |]+      )+    -- jww (2018-05-09): These two are failing but they shouldn't be+    --+    -- , ( "[ 7 13 ]"+    --   , [text|+    --       let e = 1;+    --           f = 1;+    --           t = {};+    --           s = {+    --             inherit t e f;+    --             a = 1;+    --             "b" = 2;+    --             c.d = 3;+    --           };+    --           p = builtins.unsafeGetAttrPos "c.d" s; in+    --         [ p.line p.column ]+    --       |]+    --   ) -case_unsafegetattrpos2 =-    constantEqualText "[ 5 14 ]" [text|-      let e = 1;-          f = 1;-          t = {};-          s = {-            inherit t e f;-            a = 1;-            "b" = 2;-            c.d = 3;-          };-          p = builtins.unsafeGetAttrPos "f" s; in-      [ p.line p.column ]-    |]+    -- , ( "[ 7 13 ]"+    --   , [text|+    --       let e = 1;+    --           f = 1;+    --           t = {};+    --           s = {+    --             inherit t e f;+    --             a = 1;+    --             "b" = 2;+    --             c.d = 3;+    --           };+    --           p = builtins.unsafeGetAttrPos "d" s; in+    --         [ p.line p.column ]+    --       |]+    --   )+    ] -case_unsafegetattrpos3 =-    constantEqualText "[ 6 7 ]" [text|-      let e = 1;-          f = 1;-          t = {};-          s = {-            inherit t e f;-            a = 1;-            "b" = 2;-            c.d = 3;-          };-          p = builtins.unsafeGetAttrPos "a" s; in-      [ p.line p.column ]+case_fixed_points =+  constantEqualText+    [text|+      [+        {+          foobar = "foobar";+          foo = "foo";+          bar = "bar";+        }+        {+          foobar = "foo + bar";+          foo = "foo + ";+          bar = "bar";+        }+      ]     |]--case_unsafegetattrpos4 =-    constantEqualText "[ 7 7 ]" [text|-      let e = 1;-          f = 1;-          t = {};-          s = {-            inherit t e f;-            a = 1;-            "b" = 2;-            c.d = 3;-          };-          p = builtins.unsafeGetAttrPos "b" s; in-      [ p.line p.column ]+    [text|+      let+        fix = f: let x = f x; in x;+        extends = f: rattrs: self:+          let super = rattrs self; in super // f self super;+        f = self: { foo = "foo";+                    bar = "bar";+                    foobar = self.foo + self.bar; };+        g = self: super: { foo = super.foo + " + "; };+      in [ (fix f) (fix (extends g f)) ]     |] --- jww (2018-05-09): These two are failing but they shouldn't be---- case_unsafegetattrpos5 =---     constantEqualText "[ 7 13 ]" [text|---       let e = 1;---           f = 1;---           t = {};---           s = {---             inherit t e f;---             a = 1;---             "b" = 2;---             c.d = 3;---           };---           p = builtins.unsafeGetAttrPos "c.d" s; in---       [ p.line p.column ]---     |]---- case_unsafegetattrpos6 =---     constantEqualText "[ 7 13 ]" [text|---       let e = 1;---           f = 1;---           t = {};---           s = {---             inherit t e f;---             a = 1;---             "b" = 2;---             c.d = 3;---           };---           p = builtins.unsafeGetAttrPos "d" s; in---       [ p.line p.column ]---     |]--case_fixed_points =-    constantEqualText [text|[-  {-    foobar = "foobar";-    foo = "foo";-    bar = "bar";-  }-  {-    foobar = "foo + bar";-    foo = "foo + ";-    bar = "bar";-  }-]|] [text|-    let-      fix = f: let x = f x; in x;-      extends = f: rattrs: self:-        let super = rattrs self; in super // f self super;-      f = self: { foo = "foo";-                  bar = "bar";-                  foobar = self.foo + self.bar; };-      g = self: super: { foo = super.foo + " + "; };-    in [ (fix f) (fix (extends g f)) ]-|]- case_fixed_points_and_fold =-    constantEqualText [text|[ {} {} ]|] [text|-let-  extends = f: rattrs: self:-    let super = rattrs self; in super // f self super;-  flip = f: a: b: f b a;-  toFixFold = builtins.foldl' (flip extends) (self: {}) ([(self: super: {})]);-  toFix = extends (self: super: {}) (self: {});-  fix = f: let x = f x; in x;-in [ (fix toFixFold) (fix toFix) ]-|]+  constantEqualText+    [text|+      [ {} {} ]+    |]+    [text|+      let+        extends = f: rattrs: self:+          let super = rattrs self; in super // f self super;+        flip = f: a: b: f b a;+        toFixFold = builtins.foldl' (flip extends) (self: {}) ([(self: super: {})]);+        toFix = extends (self: super: {}) (self: {});+        fix = f: let x = f x; in x;+      in [ (fix toFixFold) (fix toFix) ]+    |]  case_fixed_points_attrsets =-    constantEqualText "{ x = { y = { z = 100; }; z = { y = 100; }; }; }" [text|+  constantEqualText+    "{ x = { y = { z = 100; }; z = { y = 100; }; }; }"+    [text|       let fix = f: let x = f x; in x;           f = self: { x.z.y = 100; x.y.z = self.x.z.y; };       in fix f     |] --- case_function_equals1 =---     constantEqualText "true" "{f = x: x;} == {f = x: x;}"---- case_function_equals2 =---     constantEqualText "true" "[(x: x)] == [(x: x)]"--case_function_equals3 =-    constantEqualText "false" "(let a = (x: x); in a == a)"--case_function_equals4 =-    constantEqualText "true" "(let a = {f = x: x;}; in a == a)"--case_function_equals5 =-    constantEqualText "true" "(let a = [(x: x)]; in a == a)"+case_function_equals =+  traverse_ (uncurry constantEqualText)+    [ -- ( "true"+      -- , "{f = x: x;} == {f = x: x;}"+      -- )+      -- ( "true"+      -- , "[(x: x)] == [(x: x)]"+      -- )+      ( "false"+      , "(let a = (x: x); in a == a)"+      )+    , ( "true"+      , "(let a = {f = x: x;}; in a == a)"+      )+    , ( "true"+      , "(let a = [(x: x)]; in a == a)"+      )+    , ( "false"+      , "builtins.pathExists \"/var/empty/invalid-directory\""+      )+    ]  case_directory_pathexists =-    constantEqualText "false" "builtins.pathExists \"/var/empty/invalid-directory\""+  constantEqualText+    "false"+    "builtins.pathExists \"/var/empty/invalid-directory\""  -- jww (2018-05-02): This constantly changes!--- case_placeholder =---   constantEqualText---       "\"/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9\""---       "builtins.placeholder \"out\""+case_placeholder =+  constantEqualText+    "\"/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9\""+    "builtins.placeholder \"out\""  case_rec_path_attr =-    constantEqualText "10"-        "let src = 10; x = rec { passthru.src = src; }; in x.passthru.src"+  constantEqualText+    "10"+    "let src = 10; x = rec { passthru.src = src; }; in x.passthru.src"  case_mapattrs_builtin =-    constantEqualText' "{ a = \"afoo\"; b = \"bbar\"; }" [text|+  constantEqualText'+    "{ a = \"afoo\"; b = \"bbar\"; }"+    [text|       (builtins.mapAttrs (x: y: x + y) {         a = "foo";         b = "bar";@@ -363,10 +443,18 @@  -- Regression test for #373 case_regression_373 :: Assertion-case_regression_373 = do-  freeVarsEqual "{ inherit a; }" ["a"]-  freeVarsEqual "rec {inherit a; }" ["a"]-  freeVarsEqual "let inherit a; in { }" ["a"]+case_regression_373 =+  traverse_ (uncurry freeVarsEqual)+    [ ( "{ inherit a; }"+      , one "a"+      )+    , ("rec {inherit a; }"+      , one "a"+      )+    , ( "let inherit a; in { }"+      , one "a"+      )+    ]  case_expression_split =   constantEqualText@@ -374,91 +462,145 @@     "(x: builtins.deepSeq x x) (builtins.split \"(a)b\" \"abc\")"  case_empty_string_equal_null_is_false =-  constantEqualText "false" "\"\" == null"+  constantEqualText+    "false"+    "\"\" == null"  case_null_equal_empty_string_is_false =-  constantEqualText "false" "null == \"\""+  constantEqualText+    "false"+    "null == \"\""  case_empty_string_not_equal_null_is_true =-  constantEqualText "true" "\"\" != null"+  constantEqualText+    "true"+    "\"\" != null"  case_null_equal_not_empty_string_is_true =-  constantEqualText "true" "null != \"\""+  constantEqualText+    "true"+    "null != \"\""  case_list_nested_bottom_diverges =-  assertNixEvalThrows "let nested = [(let x = x; in x)]; in nested == nested"+  assertNixEvalThrows+    "let nested = [(let x = x; in x)]; in nested == nested"  case_attrset_nested_bottom_diverges =-  assertNixEvalThrows "let nested = { y = (let x = x; in x); }; in nested == nested"+  assertNixEvalThrows+    "let nested = { y = (let x = x; in x); }; in nested == nested"  case_list_list_nested_bottom_equal =-  constantEqualText "true" "let nested = [[(let x = x; in x)]]; in nested == nested"+  constantEqualText+    "true"+    "let nested = [[(let x = x; in x)]]; in nested == nested"  case_list_attrset_nested_bottom_equal =-  constantEqualText "true" "let nested = [{ y = (let x = x; in x); }]; in nested == nested"+  constantEqualText+    "true"+    "let nested = [{ y = (let x = x; in x); }]; in nested == nested"  case_list_function_nested_bottom_equal =-  constantEqualText "true" "let nested = [(_: let x = x; in x)]; in nested == nested"+  constantEqualText+    "true"+    "let nested = [(_: let x = x; in x)]; in nested == nested"  case_attrset_list_nested_bottom_equal =-  constantEqualText "true" "let nested = { y = [(let x = x; in x)];}; in nested == nested"+  constantEqualText+    "true"+    "let nested = { y = [(let x = x; in x)];}; in nested == nested"  case_attrset_attrset_nested_bottom_equal =-  constantEqualText "true" "let nested = { y = { y = (let x = x; in x); }; }; in nested == nested"+  constantEqualText+    "true"+    "let nested = { y = { y = (let x = x; in x); }; }; in nested == nested"  case_attrset_function_nested_bottom_equal =-  constantEqualText "true" "let nested = { y = _: (let x = x; in x); }; in nested == nested"+  constantEqualText+    "true"+    "let nested = { y = _: (let x = x; in x); }; in nested == nested"  -- Regression test for #527  case_add_string_thunk_left =-  constantEqualText [text|"cygwin"|] [text|builtins.head ["cyg"] + "win"|]+  constantEqualText+    [text|+      "cygwin"+    |]+    [text|+      builtins.head ["cyg"] + "win"+    |]  case_add_string_thunk_right =-  constantEqualText [text|"cygwin"|] [text|"cyg" + builtins.head ["win"]|]+  constantEqualText+    [text|+      "cygwin"+    |]+    [text|+      "cyg" + builtins.head ["win"]+    |]  case_add_int_thunk_left =-  constantEqualText "3" "builtins.head [1] + 2"+  constantEqualText+    "3"+    "builtins.head [1] + 2"  case_add_int_thunk_right =-  constantEqualText "3" "1 + builtins.head [2]"+  constantEqualText+    "3"+    "1 + builtins.head [2]"  case_concat_thunk_left =-  constantEqualText "[1 2 3]" "builtins.tail [0 1 2] ++ [3]"+  constantEqualText+    "[1 2 3]"+    "builtins.tail [0 1 2] ++ [3]"  case_concat_thunk_rigth =-  constantEqualText "[1 2 3]" "[1] ++ builtins.tail [1 2 3]"+  constantEqualText+    "[1 2 3]"+    "[1] ++ builtins.tail [1 2 3]"  ---------------------------------------------------------------------------------  tests :: TestTree tests = $testGroupGenerator -genEvalCompareTests = do-    td <- D.listDirectory testDir+genEvalCompareTests =+  do+    (coerce -> files :: [Path]) <- D.listDirectory $ coerce testDir -    let unmaskedFiles = filter ((==".nix") . takeExtension) td-    let files = unmaskedFiles \\ maskedFiles+    let+      unmaskedFiles :: [Path]+      unmaskedFiles = filter ((== ".nix") . takeExtension) files -    pure $ testGroup "Eval comparison tests" $ fmap (mkTestCase testDir) files+      testFiles :: [Path]+      testFiles = unmaskedFiles \\ maskedFiles++    pure $ testGroup "Eval comparison tests" $ fmap (mkTestCase testDir) testFiles   where-    mkTestCase td f = testCase f $ assertEvalFileMatchesNix (td </> f)+    mkTestCase :: Path -> Path -> TestTree+    mkTestCase dir f = testCase (coerce f :: TestName) $ assertEvalFileMatchesNix $ dir </> f  constantEqual :: NExprLoc -> NExprLoc -> Assertion-constantEqual expected actual = do+constantEqual expected actual =+  do     time <- getCurrentTime     let opts = defaultOptions time     -- putStrLn =<< lint (stripAnnotation a)-    (eq, expectedNF, actualNF) <- runWithBasicEffectsIO opts $ do-        expectedNF <- normalForm =<< nixEvalExprLoc mempty expected-        actualNF <- normalForm =<< nixEvalExprLoc mempty actual-        eq <- valueEqM expectedNF actualNF-        pure (eq, expectedNF, actualNF)-    let message =-                "Inequal normal forms:\n"-            <>  "Expected: " <> printNix expectedNF <> "\n"-            <>  "Actual:   " <> printNix actualNF-    assertBool message eq+    (eq, expectedNF, actualNF) <-+      runWithBasicEffectsIO opts $+        do+          expectedNF <- getNormForm expected+          actualNF <- getNormForm actual+          eq <- valueEqM expectedNF actualNF+          pure (eq, expectedNF, actualNF)+    let+      message =+        "Inequal normal forms:\n"+        <> "Expected: " <> printNix expectedNF <> "\n"+        <>  "Actual:   " <> printNix actualNF+    assertBool (toString message) eq+ where+  getNormForm = normalForm <=< nixEvalExprLoc mempty  constantEqualText' :: Text -> Text -> Assertion constantEqualText' expected actual =@@ -467,11 +609,11 @@     constantEqual expected' actual'  constantEqualText :: Text -> Text -> Assertion-constantEqualText expected actual = do-  constantEqualText' expected actual-  mres <- liftIO $ lookupEnv "ALL_TESTS" <|> lookupEnv "MATCHING_TESTS"-  when (isJust mres) $-      assertEvalMatchesNix actual+constantEqualText expected actual =+  do+    constantEqualText' expected actual+    mres <- liftIO $ on (<|>) lookupEnv "ALL_TESTS" "MATCHING_TESTS"+    whenJust (const $ assertEvalMatchesNix actual) mres  assertNixEvalThrows :: Text -> Assertion assertNixEvalThrows a =@@ -497,11 +639,10 @@       Right a' = parseNixText a       xs' = S.fromList xs       free' = freeVars a'-    assertEqual "" xs' free'+    assertEqual mempty xs' free' -maskedFiles :: [FilePath]-maskedFiles =-  [ "builtins.fetchurl-01.nix" ]+maskedFiles :: [Path]+maskedFiles = one "builtins.fetchurl-01.nix" -testDir :: FilePath+testDir :: Path testDir = "tests/eval-compare"
tests/Main.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE QuasiQuotes #-}+{-# language QuasiQuotes #-}  module Main where -import           Prelude hiding (lookupEnv)+import           Relude (force) import           Relude.Unsafe (read) import qualified Control.Exception as Exc import           GHC.Err (errorWithoutStackTrace)@@ -25,9 +25,9 @@ import qualified ReduceExprTests import qualified PrettyParseTests import           System.Directory-import           System.Environment (setEnv, lookupEnv)-import           System.FilePath.Glob-import           System.Posix.Files+import           System.Environment (setEnv)+import           System.FilePath.Glob (compile, globDir1)+import           System.PosixCompat.Files import           Test.Tasty import           Test.Tasty.HUnit @@ -43,9 +43,9 @@ ensureNixpkgsCanParse :: Assertion ensureNixpkgsCanParse =   consider "default.nix" (parseNixFile "default.nix") $ \case-    Fix (NAbs (ParamSet params _ _) _) -> do-      let rev    = getString "rev" params-          sha256 = getString "sha256" params+    Fix (NAbs (ParamSet _ _ pset) _) -> do+      let rev    = getString "rev" pset+          sha256 = getString "sha256" pset       consider "fetchTarball expression" (pure $ parseNixTextLoc [text|         builtins.fetchTarball {           url    = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";@@ -64,26 +64,27 @@         when (null files) $           errorWithoutStackTrace $             "Directory " <> show dir <> " does not have any files"-        for_ files $ \file -> do+        for_ files $ \file ->           unless ("azure-cli/default.nix" `isSuffixOf` file ||                   "os-specific/linux/udisks/2-default.nix"  `isSuffixOf` file) $ do             -- Parse and deepseq the resulting expression tree, to ensure the             -- parser is fully executed.-            _ <- consider file (parseNixFileLoc file) $ Exc.evaluate . force-            pass+            _ <- consider (coerce file) (parseNixFileLoc (coerce file)) $ Exc.evaluate . force+            stub     v -> fail $ "Unexpected parse from default.nix: " <> show v  where-  getExpr   k m = let Just (Just r) = lookup k m in r+  getExpr   k m =+    let Just (Just r) = lookup k m in+    r   getString k m =-      let Fix (NStr (DoubleQuoted [Plain str])) = getExpr k m in str+    let Fix (NStr (DoubleQuoted [Plain str])) = getExpr k m in+    str    consider path action k =-    do-      x <- action-      either-        (\ err -> errorWithoutStackTrace $ "Parsing " <> path <> " failed: " <> show err)-        k-        x+    either+      (\ err -> errorWithoutStackTrace $ "Parsing " <> coerce @Path path <> " failed: " <> show err)+      k+      =<< action  main :: IO () main = do@@ -94,18 +95,18 @@   prettyTestsEnv      <- lookupEnv "PRETTY_TESTS"    pwd <- getCurrentDirectory-  setEnv "NIX_REMOTE" (pwd <> "/real-store")-  setEnv "NIX_DATA_DIR" (pwd <> "/data")+  setEnv "NIX_REMOTE" $ pwd <> "/real-store"+  setEnv "NIX_DATA_DIR" $ pwd <> "/data"    defaultMain $ testGroup "hnix" $     [ ParserTests.tests     , EvalTests.tests     , PrettyTests.tests-    , ReduceExprTests.tests] <>-    [ PrettyParseTests.tests-        (fromIntegral (read (fromMaybe "0" prettyTestsEnv) :: Int)) ] <>-    [ evalComparisonTests ] <>-    [ testCase "Nix language tests present" ensureLangTestsPresent+    , ReduceExprTests.tests+    , PrettyParseTests.tests $ fromIntegral $ read @Int $ fromMaybe "0" prettyTestsEnv+    , evalComparisonTests+    , testCase "Nix language tests present" ensureLangTestsPresent     , nixLanguageTests ] <>     [ testCase "Nixpkgs parses without errors" ensureNixpkgsCanParse-      | isJust nixpkgsTestsEnv ]+      | isJust nixpkgsTestsEnv+    ]
tests/NixLanguageTests.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE ScopedTypeVariables #-}  module NixLanguageTests (genTests) where @@ -11,7 +10,6 @@ import qualified Data.Set                      as Set import qualified Data.String                   as String import qualified Data.Text                     as Text-import qualified Data.Text.IO                  as Text import           Data.Time import           GHC.Exts import           Nix.Lint@@ -22,8 +20,7 @@ import           Nix.String import           Nix.XML import qualified Options.Applicative           as Opts-import           System.Environment-import           System.FilePath+import           System.Environment             ( setEnv ) import           System.FilePath.Glob           ( compile                                                 , globDir1                                                 )@@ -61,118 +58,173 @@ newFailingTests = Set.fromList   [ "eval-okay-hash"   , "eval-okay-hashfile"-  , "eval-okay-path"+  , "eval-okay-path"  -- #128   , "eval-okay-types"   , "eval-okay-fromTOML"-  , "eval-okay-context-introspection"   ] +-- | Upstream tests that test cases that HNix disaded as a misfeature that is used so rarely+-- that it more effective to fix it & lint it out of existance.+deprecatedRareNixQuirkTests :: Set String+deprecatedRareNixQuirkTests = Set.fromList $+  one+    -- A rare quirk of Nix that is proper to fix&enforce then to support (see git commit history)+    "eval-okay-strings-as-attrs-names"+ genTests :: IO TestTree-genTests = do-  testFiles <--    sort-        -- jww (2018-05-07): Temporarily disable this test until #128 is fixed.-    .   filter ((`Set.notMember` newFailingTests) . takeBaseName)-    .   filter ((/= ".xml") . takeExtension)-    <$> globDir1 (compile "*-*-*.*") "data/nix/tests/lang"-  let testsByName = groupBy (takeFileName . dropExtensions) testFiles-  let testsByType = groupBy testType (Map.toList testsByName)-  let testGroups  = fmap mkTestGroup (Map.toList testsByType)-  pure $ localOption (mkTimeout 2000000) $ testGroup-    "Nix (upstream) language tests"-    testGroups+genTests =+  do+    testFiles <- getTestFiles+    let+      testsGroupedByName :: Map Path [Path]+      testsGroupedByName = groupBy (takeFileName . dropExtensions) testFiles++      testsGroupedByTypeThenName :: Map [String] [(Path, [Path])]+      testsGroupedByTypeThenName = groupBy testType $ Map.toList testsGroupedByName++      testTree :: [TestTree]+      testTree = mkTestGroup <$> Map.toList testsGroupedByTypeThenName++    pure $+      localOption+        (mkTimeout 2000000)+        $ testGroup+            "Nix (upstream) language tests"+            testTree  where-  testType (fullpath, _files) = take 2 $ splitOn "-" $ takeFileName fullpath-  mkTestGroup (kind, tests) =-    testGroup (String.unwords kind) $ fmap (mkTestCase kind) tests-  mkTestCase kind (basename, files) = testCase (takeFileName basename) $ do-    time <- liftIO getCurrentTime-    let opts = defaultOptions time-    case kind of-      ["parse", "okay"] -> assertParse opts $ the files-      ["parse", "fail"] -> assertParseFail opts $ the files-      ["eval" , "okay"] -> assertEval opts files-      ["eval" , "fail"] -> assertEvalFail $ the files-      _                 -> fail $ "Unexpected: " <> show kind -assertParse :: Options -> FilePath -> Assertion+  getTestFiles :: IO [Path]+  getTestFiles = sortTestFiles <$> collectTestFiles+   where+    collectTestFiles :: IO [Path]+    collectTestFiles = coerce (globDir1 (compile "*-*-*.*") nixTestDir)++    sortTestFiles :: [Path] -> [Path]+    sortTestFiles =+      sort+        -- Disabling the not yet done tests cases.+        . filter withoutDisabledTests+        . filter withoutXml+     where+      withoutDisabledTests :: Path -> Bool+      withoutDisabledTests = (`Set.notMember` (newFailingTests `Set.union` deprecatedRareNixQuirkTests)) . takeBaseName++      withoutXml :: Path -> Bool+      withoutXml = (/= ".xml") . takeExtension++  testType :: (Path, b) -> [String]+  testType (fullpath, _files) = coerce (take 2 . splitOn "-") $ takeFileName fullpath++  mkTestGroup :: ([String], [(Path, [Path])]) -> TestTree+  mkTestGroup (tType, tests) =+    testGroup (String.unwords tType) $ mkTestCase <$> tests+   where+    mkTestCase :: (Path, [Path]) -> TestTree+    mkTestCase (basename, files) =+      testCase+        (coerce $ takeFileName basename)+        $ do+            time <- liftIO getCurrentTime+            let opts = defaultOptions time+            case tType of+              ["parse", "okay"] -> assertParse opts $ the files+              ["parse", "fail"] -> assertParseFail opts $ the files+              ["eval" , "okay"] -> assertEval opts files+              ["eval" , "fail"] -> assertEvalFail $ the files+              _                 -> fail $ "Unexpected: " <> show tType+++assertParse :: Options -> Path -> Assertion assertParse _opts file =-  do-    x <- parseNixFileLoc file-    either-      (\ err -> assertFailure $ "Failed to parse " <> file <> ":\n" <> show err)-      (const pass)  -- pure $! runST $ void $ lint opts expr-      x+  either+    (\ err -> assertFailure $ "Failed to parse " <> coerce file <> ":\n" <> show err)+    (const stub)  -- pure $! runST $ void $ lint opts expr+    =<< parseNixFileLoc file -assertParseFail :: Options -> FilePath -> Assertion-assertParseFail opts file = do-  eres <- parseNixFileLoc file-  (`catch` \(_ :: SomeException) -> pass)-    (either-      (const pass)+assertParseFail :: Options -> Path -> Assertion+assertParseFail opts file =+  (`catch` \(_ :: SomeException) -> stub) $+    either+      (const stub)       (\ expr ->         do           _ <- pure $! runST $ void $ lint opts expr-          assertFailure $ "Unexpected success parsing `" <> file <> ":\nParsed value: " <> show expr+          assertFailure $ "Unexpected success parsing `" <> coerce file <> ":\nParsed value: " <> show expr       )-      eres-    )+      =<< parseNixFileLoc file -assertLangOk :: Options -> FilePath -> Assertion-assertLangOk opts file = do-  actual   <- printNix <$> hnixEvalFile opts (file <> ".nix")-  expected <- Text.readFile $ file <> ".exp"-  assertEqual "" expected $ toText (actual <> "\n")+assertLangOk :: Options -> Path -> Assertion+assertLangOk opts fileBaseName =+  do+    actual   <- printNix <$> hnixEvalFile opts (addNixExt fileBaseName)+    expected <- read fileBaseName ".exp"+    assertEqual mempty expected (actual <> "\n") -assertLangOkXml :: Options -> FilePath -> Assertion-assertLangOkXml opts file = do-  actual <- stringIgnoreContext . toXML <$> hnixEvalFile-    opts-    (file <> ".nix")-  expected <- Text.readFile $ file <> ".exp.xml"-  assertEqual "" expected actual+assertLangOkXml :: Options -> Path -> Assertion+assertLangOkXml opts fileBaseName =+  do+    actual <- stringIgnoreContext . toXML <$> hnixEvalFile opts (addNixExt fileBaseName)+    expected <- read fileBaseName ".exp.xml"+    assertEqual mempty expected actual -assertEval :: Options -> [FilePath] -> Assertion-assertEval _opts files = do-  time <- liftIO getCurrentTime-  let opts = defaultOptions time-  case delete ".nix" $ sort $ fmap takeExtensions files of-    []                 -> () <$ hnixEvalFile opts (name <> ".nix")-    [".exp"         ]  -> assertLangOk opts name-    [".exp.xml"     ]  -> assertLangOkXml opts name-    [".exp.disabled"]  -> pass-    [".exp-disabled"]  -> pass-    [".exp", ".flags"] -> do-      liftIO $ setEnv "NIX_PATH" "lang/dir4:lang/dir5"-      flags <- Text.readFile (name <> ".flags")-      let flags' | Text.last flags == '\n' = Text.init flags-                 | otherwise               = flags-      case-          Opts.execParserPure-            Opts.defaultPrefs-            (nixOptionsInfo time)-            (fixup (fmap toString (Text.splitOn " " flags')))-        of-          Opts.Failure err   -> errorWithoutStackTrace $ "Error parsing flags from " <> name <> ".flags: " <> show err-          Opts.Success opts' -> assertLangOk opts' name-          Opts.CompletionInvoked _ -> fail "unused"-    _ -> assertFailure $ "Unknown test type " <> show files+assertEval :: Options -> [Path] -> Assertion+assertEval _opts files =+  do+    time <- liftIO getCurrentTime+    let opts = defaultOptions time+    case delete ".nix" $ sort $ fromString @Text . takeExtensions <$> files of+      []                  -> void $ hnixEvalFile opts (addNixExt name)+      [".exp"          ]  -> assertLangOk    opts name+      [".exp.xml"      ]  -> assertLangOkXml opts name+      [".exp.disabled" ]  -> stub+      [".exp-disabled" ]  -> stub+      [".exp", ".flags"]  ->+        do+          liftIO $ setEnv "NIX_PATH" "lang/dir4:lang/dir5"+          flags <- read name ".flags"+          let+            flags' :: Text+            flags' =+              bool+                id+                Text.init+                (Text.last flags == '\n')+                flags+          case runParserGetResult time flags' of+            Opts.Failure           err   -> errorWithoutStackTrace $ "Error parsing flags from " <> coerce name <> ".flags: " <> show err+            Opts.CompletionInvoked _     -> fail "unused"+            Opts.Success           opts' -> assertLangOk opts' name+      _ -> assertFailure $ "Unknown test type " <> show files  where-  name =-    "data/nix/tests/lang/" <> the (fmap (takeFileName . dropExtensions) files)+  runParserGetResult :: UTCTime -> Text -> Opts.ParserResult Options+  runParserGetResult time flags' =+    Opts.execParserPure+      Opts.defaultPrefs+      (nixOptionsInfo time)+      (fmap toString $ fixup $ Text.splitOn " " flags') -  fixup ("--arg"    : x : y : rest) = "--arg" : (x <> "=" <> y) : fixup rest+  name :: Path+  name = coerce nixTestDir <> the (takeFileName . dropExtensions <$> files)++  fixup :: [Text] -> [Text]+  fixup ("--arg"    : x : y : rest) = "--arg"    : (x <> "=" <> y) : fixup rest   fixup ("--argstr" : x : y : rest) = "--argstr" : (x <> "=" <> y) : fixup rest-  fixup (x                  : rest) = x : fixup rest+  fixup (x                  : rest) =                          x  : fixup rest   fixup []                          = mempty -assertEvalFail :: FilePath -> Assertion-assertEvalFail file = (`catch` (\(_ :: SomeException) -> pass)) $ do-  time       <- liftIO getCurrentTime-  evalResult <- printNix <$> hnixEvalFile (defaultOptions time) file-  evalResult `seq`-    assertFailure $-      file-      <> " should not evaluate.\nThe evaluation result was `"-      <> evalResult-      <> "`."+assertEvalFail :: Path -> Assertion+assertEvalFail file =+  (`catch` (\(_ :: SomeException) -> stub)) $+  do+    time       <- liftIO getCurrentTime+    evalResult <- printNix <$> hnixEvalFile (defaultOptions time) file+    evalResult `seq` assertFailure $ "File: ''" <> coerce file <> "'' should not evaluate.\nThe evaluation result was `" <> toString evalResult <> "`."++nixTestDir :: FilePath+nixTestDir = "data/nix/tests/lang/"++addNixExt :: Path -> Path+addNixExt path = addExtension path ".nix"++read :: Path -> String -> IO Text+read path ext = readFile $ addExtension path ext
tests/ParserTests.hs view
@@ -1,13 +1,16 @@-{-# LANGUAGE QuasiQuotes #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE RankNTypes #-}+{-# language QuasiQuotes #-}+{-# language TemplateHaskell #-}+{-# language RankNTypes #-}+{-# language ExtendedDefaultRules #-} -{-# OPTIONS_GHC -fno-warn-name-shadowing #-}-{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# options_ghc -fno-warn-name-shadowing #-}+{-# options_ghc -Wno-missing-signatures #-}+{-# options_ghc -Wno-type-defaults #-}   module ParserTests (tests) where +import Prelude hiding (($<)) import Data.Fix import NeatInterpolation (text) import Nix.Atoms@@ -19,314 +22,523 @@ import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.TH+import Prettyprinter.Render.String (renderString)+import Prettyprinter.Util (reflow) -case_constant_int = assertParseText "234" $ mkInt 234+default (NixLang) -case_constant_bool = do-  assertParseText "true" $ mkBool True-  assertParseText "false" $ mkBool False+-- * Tests -case_constant_bool_respects_attributes = do-  assertParseText "true-foo"  $ mkSym "true-foo"-  assertParseText "false-bar" $ mkSym "false-bar" -case_constant_path = do-  assertParseText "./." $ mkPath False "./."-  assertParseText "./+-_/cdef/09ad+-" $ mkPath False "./+-_/cdef/09ad+-"-  assertParseText "/abc" $ mkPath False "/abc"-  assertParseText "../abc" $ mkPath False "../abc"-  assertParseText "<abc>" $ mkPath True "abc"-  assertParseText "<../cdef>" $ mkPath True "../cdef"-  assertParseText "a//b" $ mkOper2 NUpdate (mkSym "a") (mkSym "b")-  assertParseText "rec+def/cdef" $ mkPath False "rec+def/cdef"-  assertParseText "a/b//c/def//<g> < def/d" $ mkOper2 NLt-    (mkOper2 NUpdate (mkPath False "a/b") $ mkOper2 NUpdate-      (mkPath False "c/def") (mkPath True "g"))-    (mkPath False "def/d")-  assertParseText "a'b/c" $ Fix $ NBinary NApp (mkSym "a'b") (mkPath False "/c")-  assertParseText "a/b" $ mkPath False "a/b"-  assertParseText "4/2" $ mkPath False "4/2"-  assertParseFail "."-  assertParseFail ".."-  assertParseFail "/"-  assertParseFail "a/"-  assertParseFail "a/def/"-  assertParseFail "~"-  assertParseFail "~/"-  assertParseText "~/a" $ mkPath False "~/a"-  assertParseText "~/a/b" $ mkPath False "~/a/b"+-- ** Literals -case_constant_uri = do-  assertParseText "a:a" $ mkStr "a:a"-  assertParseText "http://foo.bar" $ mkStr "http://foo.bar"-  assertParseText "a+de+.adA+-:%%%ads%5asdk&/" $ mkStr "a+de+.adA+-:%%%ads%5asdk&/"-  assertParseText "rec+def:c" $ mkStr "rec+def:c"-  assertParseText "f.foo:bar" $ mkStr "f.foo:bar"-  assertParseFail "http://foo${\"bar\"}"-  assertParseFail ":bcdef"-  assertParseFail "a%20:asda"-  assertParseFail ".:adasd"-  assertParseFail "+:acdcd"+case_constant_int =+  checks+    ( mkInt 234+    , "234"+    ) -case_simple_set = do-  assertParseText "{ a = 23; b = 4; }" $ Fix $ NSet NNonRecursive-    [ NamedVar (mkSelector "a") (mkInt 23) nullPos-    , NamedVar (mkSelector "b") (mkInt 4) nullPos-    ]-  assertParseFail "{ a = 23 }"+case_constant_bool =+  checks+    ( mkBool True+    , "true"+    )+    ( mkBool False+    , "false"+    ) -case_set_inherit = do-  assertParseText "{ e = 3; inherit a b; }" $ Fix $ NSet NNonRecursive-    [ NamedVar (mkSelector "e") (mkInt 3) nullPos-    , Inherit Nothing (StaticKey <$> ["a", "b"]) nullPos-    ]-  assertParseText "{ inherit; }" $ Fix $ NSet NNonRecursive [ Inherit Nothing mempty nullPos ]+case_constant_bool_respects_attributes =+  invariantVals+    "true-foo"+    "false-bar" -case_set_scoped_inherit = assertParseText "{ inherit (a) b c; e = 4; inherit(a)b c; }" $ Fix $ NSet NNonRecursive-  [ Inherit (pure (mkSym "a")) (StaticKey <$> ["b", "c"]) nullPos-  , NamedVar (mkSelector "e") (mkInt 4) nullPos-  , Inherit (pure (mkSym "a")) (StaticKey <$> ["b", "c"]) nullPos-  ]+case_constant_path_invariants =+  knownAs (staysInvariantUnder (mkRelPath . toString))+    "./."+    "./+-_/cdef/09ad+-"+    "/abc"+    "../abc"+    "~/a"+    "~/a/b"+    "a/b"+    "4/2"+    "rec+def/cdef" -case_set_rec = assertParseText "rec { a = 3; b = a; }" $ Fix $ NSet NRecursive-  [ NamedVar (mkSelector "a") (mkInt 3) nullPos-  , NamedVar (mkSelector "b") (mkSym "a") nullPos-  ]+case_constant_path =+  checks+    ( var "a'b" @@ mkRelPath "/c"+    , "a'b/c"+    )+    ( mkRelPath "a/b" $// mkRelPath "c/def" $// mkEnvPath "g" $<  mkRelPath "def/d"+    , "a/b//c/def//<g> < def/d"+    )+    ( mkEnvPath "abc"+    , "<abc>"+    )+    ( mkEnvPath "../cdef"+    , "<../cdef>"+    )+    ( var "a" $// var "b"+    , "a//b"+    ) -case_set_complex_keynames = do-  assertParseText "{ \"\" = null; }" $ Fix $ NSet NNonRecursive-    [ NamedVar (DynamicKey (Plain (DoubleQuoted mempty)) :| mempty) mkNull nullPos ]-  assertParseText "{ a.b = 3; a.c = 4; }" $ Fix $ NSet NNonRecursive-    [ NamedVar (StaticKey "a" :| [StaticKey "b"]) (mkInt 3) nullPos-    , NamedVar (StaticKey "a" :| [StaticKey "c"]) (mkInt 4) nullPos-    ]-  assertParseText "{ ${let a = \"b\"; in a} = 4; }" $ Fix $ NSet NNonRecursive-    [ NamedVar (DynamicKey (Antiquoted letExpr) :| mempty) (mkInt 4) nullPos ]-  assertParseText "{ \"a${let a = \"b\"; in a}c\".e = 4; }" $ Fix $ NSet NNonRecursive-    [ NamedVar (DynamicKey (Plain str) :| [StaticKey "e"]) (mkInt 4) nullPos ]+case_constant_path_syntax_mistakes =+  mistakes+    "."+    ".."+    "/"+    "a/"+    "a/def/"+    "~"+    "~/"++case_constant_uri =+  knownAs (staysInvariantUnder mkStr)+    "a:a"+    "http://foo.bar"+    "a+de+.adA+-:%%%ads%5asdk&/"+    "rec+def:c"+    "f.foo:bar"+++case_constant_uri_syntax_mistakes =+  mistakes+    "http://foo${\"bar\"}"+    ":bcdef"+    "a%20:asda"+    ".:adasd"+    "+:acdcd"+++-- *** Special chars in vals++case_identifier_special_chars =+  invariantVals+    "_a"+    "a_b"+    "a'b"+    "a''b"+    "a-b"+    "a--b"+    "a12a"++case_identifier_special_chars_syntax_mistakes =+  mistakes+    ".a"+    "'a"++-- ** Sets++-- *** Non-recursive sets++case_simple_set =+  checks+    ( mkNonRecSet+        [ "a" $= mkInt 23+        , "b" $= mkInt  4+        ]+    , "{ a = 23; b = 4; }"+    )++case_simple_set_syntax_mistakes =+  mistakes+    "{ a = 23 }"++case_set_complex_keynames =+  checks+    ( mkNonRecSet $+        one (NamedVar (one (DynamicKey (Plain (DoubleQuoted mempty)))) mkNull nullPos)+    , "{ \"\" = null; }"+    )+    ( mkNonRecSet+        [ NamedVar (StaticKey "a" :| one (StaticKey "b")) (mkInt 3) nullPos+        , NamedVar (StaticKey "a" :| one (StaticKey "c")) (mkInt 4) nullPos+        ]+    , "{ a.b = 3; a.c = 4; }"+    )+    ( mkNonRecSet $+        one (NamedVar (one (DynamicKey (Antiquoted letExpr))) (mkInt 4) nullPos)+    , "{ ${let a = \"b\"; in a} = 4; }"+    )+    ( mkNonRecSet $+        one (NamedVar (DynamicKey (Plain str) :| one (StaticKey "e")) (mkInt 4) nullPos)+    , "{ \"a${let a = \"b\"; in a}c\".e = 4; }"+    )  where-  letExpr = Fix $ NLet [NamedVar (mkSelector "a") (mkStr "b") nullPos] (mkSym "a")+  letExpr = mkLets (one ("a" $= mkStr "b")) (var "a")   str = DoubleQuoted [Plain "a", Antiquoted letExpr, Plain "c"] -case_set_inherit_direct = assertParseText "{ inherit ({a = 3;}); }" $ Fix $ NSet NNonRecursive-  [ Inherit (pure $ Fix $ NSet NNonRecursive [NamedVar (mkSelector "a") (mkInt 3) nullPos]) mempty nullPos-  ] -case_inherit_selector = do-  assertParseText "{ inherit \"a\"; }" $ Fix $ NSet NNonRecursive-    [Inherit Nothing [DynamicKey (Plain (DoubleQuoted [Plain "a"]))] nullPos]-  assertParseFail "{ inherit a.x; }"+-- *** Recursivity in sets -case_int_list = assertParseText "[1 2 3]" $ Fix $ NList-  [ mkInt i | i <- [1,2,3] ]+case_set_rec =+  checks+    ( mkRecSet+        [ "a" $= mkInt 3+        , "b" $= var "a"+        ]+    , "rec { a = 3; b = a; }"+    ) -case_int_null_list = assertParseText "[1 2 3 null 4]" $ Fix (NList (fmap (Fix . NConstant) [NInt 1, NInt 2, NInt 3, NNull, NInt 4])) -case_mixed_list = do-  assertParseText "[{a = 3;}.a (if true then null else false) null false 4 [] c.d or null]" $ Fix $ NList-    [ Fix (NSelect (Fix (NSet NNonRecursive [NamedVar (mkSelector "a") (mkInt 3) nullPos]))-                   (mkSelector "a") Nothing)-    , Fix (NIf (mkBool True) mkNull (mkBool False))-    , mkNull, mkBool False, mkInt 4, Fix (NList mempty)-    , Fix (NSelect (mkSym "c") (mkSelector "d") (pure mkNull))-    ]-  assertParseFail "[if true then null else null]"-  assertParseFail "[a ? b]"-  assertParseFail "[a : a]"-  assertParseFail "[${\"test\")]"+-- *** Inheritance -case_simple_lambda = assertParseText "a: a" $ Fix $ NAbs (Param "a") (mkSym "a")+case_set_inherit =+  checks+    ( mkNonRecSet+        [ "e" $= mkInt 3+        , inherit ["a", "b"]+        ]+    , "{ e = 3; inherit a b; }"+    )+    ( mkNonRecSet $ one $ inherit mempty+    , "{ inherit; }"+    ) -case_lambda_or_uri = do-  assertParseText "a :b" $ Fix $ NAbs (Param "a") (mkSym "b")-  assertParseText "a c:def" $ Fix $ NBinary NApp (mkSym "a") (mkStr "c:def")-  assertParseText "c:def: c" $ Fix $ NBinary NApp (mkStr "c:def:") (mkSym "c")-  assertParseText "a:{}" $ Fix $ NAbs (Param "a") $ Fix $ NSet NNonRecursive mempty-  assertParseText "a:[a]" $ Fix $ NAbs (Param "a") $ Fix $ NList [mkSym "a"]-  assertParseFail "def:"+case_set_scoped_inherit =+  checks+    ( mkNonRecSet $+        (\ x -> [x, "e" $= mkInt 4, x]) $+          inheritFrom (var "a") ["b", "c"]+    , "{ inherit (a) b c; e = 4; inherit(a)b c; }"+    ) -case_lambda_pattern = do-  assertParseText "{b, c ? 1}: b" $-    Fix $ NAbs (fixed args mempty) (mkSym "b")-  assertParseText "{ b ? x: x  }: b" $-    Fix $ NAbs (fixed args2 mempty) (mkSym "b")-  assertParseText "a@{b,c ? 1}: b" $-    Fix $ NAbs (fixed args (pure "a")) (mkSym "b")-  assertParseText "{b,c?1}@a: c" $-    Fix $ NAbs (fixed args (pure "a")) (mkSym "c")-  assertParseText "{b,c?1,...}@a: c" $-    Fix $ NAbs (variadic vargs (pure "a")) (mkSym "c")-  assertParseText "{...}: 1" $-    Fix $ NAbs (variadic mempty mempty) (mkInt 1)-  assertParseFail "a@b: a"-  assertParseFail "{a}@{b}: a"+case_set_inherit_direct =+  checks+    ( mkNonRecSet $ one (inheritFrom (mkNonRecSet $ one ("a" $= mkInt 3)) mempty)+    , "{ inherit ({a = 3;}); }"+    )++case_inherit_selector_syntax_mistakes =+  mistakes+    "{ inherit a.x; }"+    -- A rare quirk of Nix that is proper to fix then to support (see git commit history)+    -- (old parser test result was):+    -- mkNonRecSet [inherit [DynamicKey (Plain (DoubleQuoted [Plain "a"]))]],+    "{ inherit \"a\"; }"+++-- ** Lists++case_int_list =+  checks+    ( mkList $ mkInt <$> [1,2,3]+    , "[1 2 3]"+    )++case_int_null_list =+  checks+    ( mkList (mkConst <$> [NInt 1, NInt 2, NInt 3, NNull, NInt 4])+    , "[1 2 3 null 4]"+    )++case_mixed_list =+  checks+    ( mkList+        [ mkNonRecSet (one $ "a" $= mkInt 3) @. "a"+        , mkIf (mkBool True) mkNull (mkBool False)+        , mkNull+        , mkBool False+        , mkInt 4+        , emptyList+        , (@.<|>) (var "c") "d" mkNull+        ]+    , "[{a = 3;}.a (if true then null else false) null false 4 [] c.d or null]"+    )++case_mixed_list_syntax_mistakes =+  mistakes+    "[if true then null else null]"+    "[a ? b]"+    "[a : a]"+    "[${\"test\")]"+++-- ** Lambdas++case_simple_lambda =+  checks+    ( mkFunction (Param "a") (var "a")+    , "a: a"+    )++case_lambda_or_uri =+  checks+    ( mkFunction (Param "a") $ var "b"+    , "a :b"+    )+    ( var "a" @@ mkStr "c:def"+    , "a c:def"+    )+    ( mkStr "c:def:" @@ var "c"+    , "c:def: c"+    )+    ( mkFunction (Param "a") emptySet+    , "a:{}"+    )+    ( mkFunction (Param "a") $ mkList $ one $ var "a"+    , "a:[a]"+    )++case_lambda_or_uri_syntax_mistakes =+  mistakes+    "def:"++case_lambda_pattern =+  checks+    ( mkFunction (mkParamSet args) $ var "b"+    , "{b, c ? 1}: b"+    -- Fix (NAbs (ParamSet [("b",Nothing),("c",Just (Fix (NConstant (NInt 1))))] False Nothing) (Fix (NSym "b")))+    )+    ( mkFunction (mkParamSet args2) $ var "b"+    , "{ b ? x: x  }: b"+    )+    ( mkFunction (mkNamedParamSet "a" args) $ var "b"+    , "a@{b,c ? 1}: b"+    )+    ( mkFunction (mkNamedParamSet "a" args) $ var "c"+    , "{b,c?1}@a: c"+    )+    ( mkFunction (mkNamedVariadicParamSet "a" vargs) $ var "c"+    , "{b,c?1,...}@a: c"+    )+    ( mkFunction (mkVariadicParamSet mempty) $ mkInt 1+    , "{...}: 1"+    )  where-  fixed args = ParamSet args False-  variadic args = ParamSet args True-  args = [("b", Nothing), ("c", pure $ mkInt 1)]+  args  = [("b", Nothing), ("c", pure $ mkInt 1)]   vargs = [("b", Nothing), ("c", pure $ mkInt 1)]-  args2 = [("b", pure lam)]-  lam = Fix $ NAbs (Param "x") (mkSym "x")+  args2 = one ("b", pure lam)+  lam = mkFunction (Param "x") $ var "x" -case_lambda_app_int = assertParseText "(a: a) 3" $ Fix (NBinary NApp lam int) where-  int = mkInt 3-  lam = Fix (NAbs (Param "a") asym)-  asym = mkSym "a"+case_lambda_pattern_syntax_mistakes =+  mistakes+    "a@b: a"+    "{a}@{b}: a" -case_simple_let = do-  assertParseText "let a = 4; in a" $ Fix (NLet binds $ mkSym "a")-  assertParseFail "let a = 4 in a"- where-  binds = [NamedVar (mkSelector "a") (mkInt 4) nullPos]+case_lambda_app_int =+  checks+    ( mkFunction (Param "a") (var "a") @@ mkInt 3+    , "(a: a) 3"+    ) -case_let_body = assertParseText "let { body = 1; }" letBody-  where-    letBody = Fix $ NSelect aset (mkSelector "body") Nothing-    aset = Fix $ NSet NRecursive [NamedVar (mkSelector "body") (mkInt 1) nullPos] -case_nested_let = do-  assertParseText "let a = 4; in let b = 5; in a" $ Fix $ NLet-    [NamedVar (mkSelector "a") (mkInt 4) nullPos]-    (Fix $ NLet [NamedVar (mkSelector "b") (mkInt 5) nullPos] $ mkSym "a")-  assertParseFail "let a = 4; let b = 3; in b"+-- ** Let -case_let_scoped_inherit = do-  assertParseText "let a = null; inherit (b) c; in c" $ Fix $ NLet-    [ NamedVar (mkSelector "a") mkNull nullPos-    , Inherit (pure $ mkSym "b") [StaticKey "c"] nullPos ]-    (mkSym "c")-  assertParseFail "let inherit (b) c in c"+case_simple_let =+  checks+    ( mkLets (one $ "a" $= mkInt 4) $ var "a"+    , "let a = 4; in a"+    ) -case_if = do-  assertParseText "if true then true else false" $-      Fix $ NIf (mkBool True) (mkBool True) (mkBool False)-  assertParseFail "if true then false"-  assertParseFail "else"-  assertParseFail "if true then false else"-  assertParseFail "if true then false else false else"-  assertParseFail "1 + 2 then"+case_simple_let_syntax_mistakes =+  mistakes+    "let a = 4 in a" -case_identifier_special_chars = do-  assertParseText "_a" $ mkSym "_a"-  assertParseText "a_b" $ mkSym "a_b"-  assertParseText "a'b" $ mkSym "a'b"-  assertParseText "a''b" $ mkSym "a''b"-  assertParseText "a-b" $ mkSym "a-b"-  assertParseText "a--b" $ mkSym "a--b"-  assertParseText "a12a" $ mkSym "a12a"-  assertParseFail ".a"-  assertParseFail "'a"+case_let_body =+  checks+    ( mkRecSet (one $ "body" $= mkInt 1) @. "body"+    , "let { body = 1; }"+    ) -case_identifier_keyword_prefix = do-  assertParseText "true-name" $ mkSym "true-name"-  assertParseText "trueName" $ mkSym "trueName"-  assertParseText "null-name" $ mkSym "null-name"-  assertParseText "nullName" $ mkSym "nullName"-  assertParseText "[ null-name ]" $ mkList [ mkSym "null-name" ]+case_nested_let =+  checks+    ( mkLets (one $ "a" $= mkInt 4) $+        mkLets (one $ "b" $= mkInt 5) $ var "a"+    , "let a = 4; in let b = 5; in a"+    ) -makeTextParseTest str = assertParseText ("\"" <> str <> "\"") $ mkStr str+case_nested_let_syntax_mistakes =+  mistakes+    "let a = 4; let b = 3; in b" -case_simple_string = traverse_ makeTextParseTest ["abcdef", "a", "A", "   a a  ", ""]+case_let_scoped_inherit =+  checks+    ( mkLets+        [ "a" $= mkNull+        , inheritFrom (var "b") $ one "c"+        ]+        $ var "c"+    , "let a = null; inherit (b) c; in c"+    ) -case_string_dollar = traverse_ makeTextParseTest ["a$b", "a$$b", "$cdef", "gh$i"]+case_let_scoped_inherit_syntax_mistakes =+  mistakes+    "let inherit (b) c in c" -case_string_escape = do-  assertParseText "\"\\$\\n\\t\\r\\\\\"" $ mkStr "$\n\t\r\\"-  assertParseText "\" \\\" \\' \"" $ mkStr " \" ' " -case_string_antiquote = do-  assertParseText "\"abc${  if true then \"def\" else \"abc\"  } g\"" $-    Fix $ NStr $ DoubleQuoted-      [ Plain "abc"-      , Antiquoted $ Fix $ NIf (mkBool True) (mkStr "def") (mkStr "abc")-      , Plain " g"-      ]-  assertParseText "\"\\${a}\"" $ mkStr "${a}"-  assertParseFail "\"a"-  assertParseFail "${true}"-  assertParseFail "\"${true\""+-- ** If -case_select = do-  assertParseText "a .  e .di. f" $ Fix $ NSelect (mkSym "a")-    (StaticKey "e" :| [StaticKey "di", StaticKey "f"])-    Nothing-  assertParseText "a.e . d    or null" $ Fix $ NSelect (mkSym "a")-    (StaticKey "e" :| [StaticKey "d"])-    (pure mkNull)-  assertParseText "{}.\"\"or null" $ Fix $ NSelect (Fix (NSet NNonRecursive mempty))-    (DynamicKey (Plain (DoubleQuoted mempty)) :| mempty) (pure mkNull)-  assertParseText "{ a = [1]; }.a or [2] ++ [3]" $ Fix $ NBinary NConcat-      (Fix (NSelect-                (Fix (NSet NNonRecursive [NamedVar (StaticKey "a" :| mempty)-                                     (Fix (NList [Fix (NConstant (NInt 1))]))-                                     nullPos]))-                (StaticKey "a" :| mempty)-                (pure (Fix (NList [Fix (NConstant (NInt 2))])))))-      (Fix (NList [Fix (NConstant (NInt 3))]))+case_if =+  checks+    ( mkIf (mkBool True) (mkBool True) (mkBool False)+    , "if true then true else false"+    ) -case_select_path = do-  assertParseText "f ./." $ Fix $ NBinary NApp (mkSym "f") (mkPath False "./.")-  assertParseText "f.b ../a" $ Fix $ NBinary NApp select (mkPath False "../a")-  assertParseText "{}./def" $ Fix $ NBinary NApp (Fix (NSet NNonRecursive mempty)) (mkPath False "./def")-  assertParseText "{}.\"\"./def" $ Fix $ NBinary NApp-    (Fix $ NSelect (Fix (NSet NNonRecursive mempty)) (DynamicKey (Plain (DoubleQuoted mempty)) :| mempty) Nothing)-    (mkPath False "./def")- where select = Fix $ NSelect (mkSym "f") (mkSelector "b") Nothing+case_if_syntax_mistakes =+  mistakes+    "if true then false"+    "else"+    "if true then false else"+    "if true then false else false else"+    "1 + 2 then" -case_select_keyword = do-  assertParseText "{ false = \"foo\"; }" $ Fix $ NSet NNonRecursive [NamedVar (mkSelector "false") (mkStr "foo") nullPos] -case_fun_app = do-  assertParseText "f a b" $ Fix $ NBinary NApp (Fix $ NBinary NApp (mkSym "f") (mkSym "a")) (mkSym "b")-  assertParseText "f a.x or null" $ Fix $ NBinary NApp (mkSym "f") $ Fix $-    NSelect (mkSym "a") (mkSelector "x") (pure mkNull)-  assertParseFail "f if true then null else null"+-- ** Literal expressions in vals -case_indented_string = do-  assertParseText "''a''" $ mkIndentedStr 0 "a"-  assertParseText "''\n  foo\n  bar''" $ mkIndentedStr 2 "foo\nbar"-  assertParseText "''        ''" $ mkIndentedStr 0 ""-  assertParseText "'''''''" $ mkIndentedStr 0 "''"-  assertParseText "''   ${null}\n   a${null}''" $ Fix $ NStr $ Indented 3-    [ Antiquoted mkNull-    , Plain "\na"-    , Antiquoted mkNull-    ]-  assertParseFail "'''''"-  assertParseFail "''   '"+case_identifier_keyword_prefix_invariants =+  invariantVals+    "true-name"+    "trueName"+    "null-name"+    "nullName" -case_indented_string_escape = assertParseText-  "'' ''\\n ''\\t ''\\\\ ''${ \\ \\n ' ''' ''" $-  mkIndentedStr 1 "\n \t \\ ${ \\ \\n ' '' "+case_identifier_keyword_prefix =+  checks+    ( mkList $ one $ var "null-name"+    , "[ null-name ]"+    ) -case_operator_fun_app = do-  assertParseText "a ++ b" $ mkOper2 NConcat (mkSym "a") (mkSym "b")-  assertParseText "a ++ f b" $ mkOper2 NConcat (mkSym "a") $ Fix $ NBinary NApp-    (mkSym "f") (mkSym "b") -case_operators = do-  assertParseText "1 + 2 - 3" $ mkOper2 NMinus-    (mkOper2 NPlus (mkInt 1) (mkInt 2)) (mkInt 3)-  assertParseFail "1 + if true then 1 else 2"-  assertParseText "1 + (if true then 2 else 3)" $ mkOper2 NPlus (mkInt 1) $ Fix $ NIf-   (mkBool True) (mkInt 2) (mkInt 3)-  assertParseText "{ a = 3; } // rec { b = 4; }" $ mkOper2 NUpdate-    (Fix $ NSet NNonRecursive [NamedVar (mkSelector "a") (mkInt 3) nullPos])-    (Fix $ NSet NRecursive [NamedVar (mkSelector "b") (mkInt 4) nullPos])-  assertParseText "--a" $ mkOper NNeg $ mkOper NNeg $ mkSym "a"-  assertParseText "a - b - c" $ mkOper2 NMinus-    (mkOper2 NMinus (mkSym "a") (mkSym "b")) $-    mkSym "c"-  assertParseText "foo<bar" $ mkOper2 NLt (mkSym "foo") (mkSym "bar")-  assertParseFail "+ 3"-  assertParseFail "foo +"+-- ** Strings -case_comments =-  do-    Right expected <- parseNixFile "data/let.nix"-    assertParseFile "let-comments-multiline.nix" expected-    assertParseFile "let-comments.nix" expected+invariantString str =+  checks+    ( mkStr str+    , "\"" <> str <> "\""+    ) +case_simple_string =+  knownAs invariantString+    "abcdef"+    "a"+    "A"+    "   a a  "+    ""++case_string_dollar =+  knownAs invariantString+    "a$b"+    "a$$b"+    "$cdef"+    "gh$i"++case_string_escape =+  checks+    ( mkStr "$\n\t\r\\"+    , "\"\\$\\n\\t\\r\\\\\""+    )+    ( mkStr " \" ' "+    , "\" \\\" \\' \""+    )++case_string_antiquote =+  checks+    ( Fix $ NStr $ DoubleQuoted+        [ Plain "abc"+        , Antiquoted $ mkIf (mkBool True) (mkStr "def") (mkStr "abc")+        , Plain " g"+        ]+    , "\"abc${  if true then \"def\" else \"abc\"  } g\""+    )+    ( mkStr "${a}"+    , "\"\\${a}\""+    )++case_string_antiquote_syntax_mistakes =+  mistakes+    "\"a"+    "${true}"+    "\"${true\""+++-- *** Indented string++case_indented_string =+  checks+    ( mkIndentedStr 0 "a"+    , "''a''"+    )+    ( mkIndentedStr 2 "foo\nbar"+    , "''\n  foo\n  bar''"+    )+    ( mkIndentedStr 0 mempty+    , "''        ''"+    )+    ( mkIndentedStr 0 "''"+    , "'''''''"+    )+    ( Fix $ NStr $ Indented 3+        [ Antiquoted mkNull+        , Plain "\na"+        , Antiquoted mkNull+        ]+    , "''   ${null}\n   a${null}''"+    )++case_indented_string_syntax_mistakes =+  mistakes+    "'''''"+    "''   '"++case_indented_string_escape =+  checks+    ( mkIndentedStr 1 "\n \t \\ ${ \\ \\n ' '' "+    , "'' ''\\n ''\\t ''\\\\ ''${ \\ \\n ' ''' ''"+    )++-- ** Selection++case_select =+  checks+    ( Fix $ NSelect Nothing (var "a") (StaticKey "e" :| [StaticKey "di", StaticKey "f"])+    , "a .  e .di. f"+    )+    ( Fix $ NSelect (pure mkNull) (var "a")+        (StaticKey "e" :| one (StaticKey "d"))+    , "a.e . d    or null"+    )+    ( Fix $ NSelect (pure mkNull) emptySet+        (one $ DynamicKey (Plain $ DoubleQuoted mempty))+    , "{}.\"\"or null"+    )+    ( Fix $ NBinary NConcat+        ((@.<|>)+          (mkNonRecSet $+            one $+              NamedVar+                (mkSelector "a")+                (mkList $ one $ mkInt 1)+                nullPos+          )+          "a"+          (mkList $ one $ mkInt 2)+        )+        (mkList $ one $ mkInt 3)+    , "{ a = [1]; }.a or [2] ++ [3]"+    )++case_select_path =+  checks+    ( var "f" @@ mkRelPath "./."+    , "f ./."+    )+    ( var "f" @. "b" @@ mkRelPath "../a"+    , "f.b ../a"+    )+    ( emptySet @@ mkRelPath "./def"+    , "{}./def"+    )+    ( Fix (NSelect Nothing emptySet $ one $ DynamicKey $ Plain $ DoubleQuoted mempty) @@ mkRelPath "./def"+    , "{}.\"\"./def"+    )++case_select_keyword =+  checks+    ( mkNonRecSet $ one $ "false" $= mkStr "foo"+    , "{ false = \"foo\"; }"+    )+ case_select_or_precedence =     assertParsePrint [text|let   matchDef = def:   matcher:@@ -357,39 +569,101 @@         in (matcher.case or null).foo (v.case); in null|] +-- ** Function application++case_fun_app =+  checks+    ( var "f" @@ var "a" @@ var "b"+    , "f a b"+    )+    ( var "f" @@ (@.<|>) (var "a") "x" mkNull+    , "f a.x or null"+    )++case_fun_app_syntax_mistakes =+  mistakes+   "f if true then null else null"+++-- ** Operators++case_operator_fun_app =+  checks+    ( var "a" $++ var "b"+    , "a ++ b"+    )+    ( var "a" $++ var "f" @@ var "b"+    , "a ++ f b"+    )++case_operators =+  checks+    ( mkInt 1 $+ mkInt 2 $- mkInt 3+    , "1 + 2 - 3"+    )+    ( mkInt 1 $+ mkIf (mkBool True) (mkInt 2) (mkInt 3)+    , "1 + (if true then 2 else 3)"+    )+    ( mkNonRecSet (one $ "a" $= mkInt 3) $// mkRecSet (one $ "b" $= mkInt 4)+    , "{ a = 3; } // rec { b = 4; }"+    )+    ( mkNeg $ mkNeg $ var "a"+    , "--a"+    )+    ( var "a" $- var "b" $- var "c"+    , "a - b - c"+    )+    ( var "foo" $< var "bar"+    , "foo<bar"+    )++case_operators_syntax_mistakes =+  mistakes+    "+ 3"+    "foo +"+    "1 + if true then 1 else 2"+++-- ** Comments++case_comments =+  do+    Right expected <- parseNixFile "data/let.nix"+    assertParseFile "let-comments-multiline.nix" expected+    assertParseFile "let-comments.nix" expected+++-- ** Location+ case_simpleLoc =   let-    mkSPos l c = SourcePos "<string>" (mkPos l) (mkPos c)-    mkSpan l1 c1 l2 c2 = SrcSpan (mkSPos l1 c1) (mkSPos l2 c2)+    mkSPos = on (SourcePos "<string>") mkPos+    mkSpan = on SrcSpan (uncurry mkSPos)   in     assertParseTextLoc [text|let     foo = bar          baz "qux";     in foo     |]-    (Fix-      (NLet_-        (mkSpan 1 1 4 7)-        [ NamedVar-            (StaticKey "foo" :| [])-            (Fix-              (NBinary_-                (mkSpan 2 7 3 15)-                NApp-                (Fix-                  (NBinary_ (mkSpan 2 7 3 9)-                            NApp-                            (Fix (NSym_ (mkSpan 2 7 2 10) "bar"))-                            (Fix (NSym_ (mkSpan 3 6 3 9) "baz"))-                  )-                )-                (Fix (NStr_ (mkSpan 3 10 3 15) (DoubleQuoted [Plain "qux"])))-              )+    (NLetAnn+      (mkSpan (1, 1) (4, 7))+      (one $+        NamedVar+          (one $ StaticKey "foo")+          (NBinaryAnn+            (mkSpan (2, 7) (3, 15))+            NApp+            (NBinaryAnn+              (mkSpan (2, 7) (3, 9))+              NApp+              (NSymAnn (mkSpan (2, 7) (2, 10)) "bar")+              (NSymAnn (mkSpan (3, 6) (3, 9 )) "baz")             )-            (mkSPos 2 1)-        ]-        (Fix (NSym_ (mkSpan 4 4 4 7) "foo"))+            (NStrAnn (mkSpan (3, 10) (3, 15)) $ DoubleQuoted $ one $ Plain "qux")+          )+          (mkSPos 2 1)       )+      (NSymAnn (mkSpan (4, 4) (4, 7)) "foo")     )  @@ -398,12 +672,42 @@  --------------------------------------------------------------------------------- -assertParseText :: Text -> NExpr -> Assertion-assertParseText str expected =+-- * Helpers++var = mkSym++invariantVal = staysInvariantUnder var++staysInvariantUnder :: (NixLang -> ExpectedHask) -> NixLang -> Assertion+staysInvariantUnder f v =+  (<=>) (f v) v++type NixLang = Text+type ExpectedHask = NExpr++(<=>) :: ExpectedHask -> NixLang -> Assertion+(<=>) = assertParseText++throwParseError :: forall ann . Text -> Text -> Doc ann -> Assertion+throwParseError entity expr err =+  assertFailure $+    renderString $+      layoutSmart Prettyprinter.defaultLayoutOptions $+        nest 2 $+          vsep+            [ mempty+            , "Unexpected fail parsing " <> reflow entity <> ":"+            , nest 2 $ vsep+              [ "Expression:"+              , reflow expr+              , "Error: " <> nest 2 err+              ]+            ]++assertParseText :: ExpectedHask -> NixLang -> Assertion+assertParseText expected str =   either-    (\ err ->-      assertFailure $ toString $ "Unexpected fail parsing `" <> str <> "':\n" <> show err-    )+    (throwParseError "expression" str)     (assertEqual       ("When parsing " <> toString str)       (stripPositionInfo expected)@@ -411,39 +715,35 @@     )     (parseNixText str) -assertParseTextLoc :: Text -> NExprLoc -> Assertion+assertParseTextLoc :: NixLang -> NExprLoc -> Assertion assertParseTextLoc str expected =   either-    (\ err ->-      assertFailure $ toString $ "Unexpected fail parsing `" <> str <> "':\n" <> show err-    )+    (throwParseError "expression" str)     (assertEqual       ("When parsing " <> toString str)       expected     )     (parseNixTextLoc str) -assertParseFile :: FilePath -> NExpr -> Assertion+assertParseFile :: Path -> NExpr -> Assertion assertParseFile file expected =   do-  res <- parseNixFile $ "data/" <> file-  either-    (\ err ->-      assertFailure $ "Unexpected fail parsing data file `" <> file <> "':\n" <> show err-    )-    (assertEqual-      ("Parsing data file " <> file)-      (stripPositionInfo expected)-      . stripPositionInfo-    )-    res+    res <- parseNixFile $ "data/" <> file+    either+      (throwParseError "data file" $ toText file)+      (assertEqual+        ("Parsing data file " <> coerce file)+        (stripPositionInfo expected)+        . stripPositionInfo+      )+      res -assertParseFail :: Text -> Assertion+assertParseFail :: NixLang -> Assertion assertParseFail str =   either-    (const pass)+    (const stub)     (\ r ->-      assertFailure $ toString $ "Unexpected success parsing `" <> str <> ":\nParsed value: " <> show r+      assertFailure $ toString $ "\nUnexpected success parsing string ''" <> str <> "'':\n''Parsed value: ''" <> show r <> "''."     )     (parseNixText str) @@ -456,8 +756,53 @@     Right expr = parseNixTextLoc src     result =       renderStrict-      . layoutPretty (LayoutOptions $ AvailablePerLine 80 0.4)+      . layoutPretty defaultLayoutOptions       . prettyNix       . stripAnnotation $         expr-  in assertEqual "" expect result+  in+  assertEqual mempty expect result+++-----++-- | This class constructs functions that accept variacic number of argumets.+-- Every argument is an assertion.+-- So now the new assertions can be added just by adding it to a block of according assertions.+class VariadicAssertions t where+  checkListPairs' :: ((ExpectedHask, NixLang) -> Assertion) -> [(ExpectedHask, NixLang)] -> t++instance VariadicAssertions (IO a) where+  checkListPairs' f acc =+    do+      traverse_ f acc+      pure $ error "never would be reached, cuz `I'm lazy`."++instance (VariadicAssertions a) => VariadicAssertions ((ExpectedHask, NixLang) -> a) where+  checkListPairs' f acc x = checkListPairs' f (acc <> one x)++checks :: (VariadicAssertions a) => a+checks = checkListPairs' (uncurry assertParseText) []+++class VariadicArgs t where+  checkList' :: (NixLang -> Assertion) -> [NixLang] -> t++instance VariadicArgs (IO a) where+  checkList' f acc =+    do+      traverse_ f acc+      pure $ error "never would be reached, cuz `I'm lazy`."++instance (VariadicArgs a) => VariadicArgs (NixLang -> a) where+  checkList' f acc x = checkList' f (acc <> one x)++knownAs :: (VariadicArgs a) => (NixLang -> Assertion) -> a+knownAs f = checkList' f []++mistakes :: (VariadicArgs a) => a+mistakes = knownAs assertParseFail++invariantVals :: (VariadicArgs a) => a+invariantVals = knownAs invariantVal+
tests/PrettyParseTests.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE MonoLocalBinds #-}-{-# LANGUAGE NoMonomorphismRestriction #-}+{-# language DataKinds #-}+{-# language MonoLocalBinds #-}+{-# language NoMonomorphismRestriction #-}   @@ -18,7 +18,6 @@ import           Nix.Expr import           Nix.Parser import           Nix.Pretty-import           Nix.Utils import           Prettyprinter import           Test.Tasty import           Test.Tasty.Hedgehog@@ -29,23 +28,26 @@ asciiString = Gen.list (Range.linear 1 15) Gen.lower  asciiText :: Gen Text-asciiText = toText <$> asciiString+asciiText = fromString <$> asciiString +asciiVarName :: Gen VarName+asciiVarName = coerce <$> asciiText+ -- Might want to replace this instance with a constant value genPos :: Gen Pos genPos = mkPos <$> Gen.int (Range.linear 1 256)  genSourcePos :: Gen SourcePos genSourcePos =-  liftA3-    SourcePos-    asciiString-    genPos+  join (liftA3+      SourcePos+      asciiString+    )     genPos  genKeyName :: Gen (NKeyName NExpr) genKeyName =-  Gen.choice [DynamicKey <$> genAntiquoted genString, StaticKey <$> asciiText]+  Gen.choice [DynamicKey <$> genAntiquoted genString, StaticKey <$> asciiVarName]  genAntiquoted :: Gen a -> Gen (Antiquoted a NExpr) genAntiquoted gen =@@ -53,51 +55,53 @@  genBinding :: Gen (Binding NExpr) genBinding = Gen.choice-  [ liftA3-      NamedVar+  [ liftA3 NamedVar       genAttrPath       genExpr       genSourcePos-  , liftA3-      Inherit+  , liftA3 Inherit       (Gen.maybe genExpr)-      (Gen.list (Range.linear 0 5) genKeyName)+      (Gen.list (Range.linear 0 5) asciiVarName)       genSourcePos   ]  genString :: Gen (NString NExpr) genString = Gen.choice-  [ DoubleQuoted <$> Gen.list (Range.linear 0 5) (genAntiquoted asciiText)-  , liftA2-      Indented-      (Gen.int (Range.linear 0 10))-      (Gen.list-        (Range.linear 0 5)-        (genAntiquoted asciiText)-      )+  [ DoubleQuoted <$> genLines+  , liftA2 Indented+      (Gen.int $ Range.linear 0 10)+      genLines   ]+ where+  genLines =+    Gen.list+      (Range.linear 0 5)+      (genAntiquoted asciiText)  genAttrPath :: Gen (NAttrPath NExpr) genAttrPath =-  liftA2-    (:|)+  liftA2 (:|)     genKeyName     $ Gen.list (Range.linear 0 4) genKeyName  genParams :: Gen (Params NExpr) genParams = Gen.choice-  [ Param <$> asciiText-  , liftA3-      ParamSet-      (Gen.list (Range.linear 0 10) (liftA2 (,) asciiText $ Gen.maybe genExpr))+  [ Param <$> asciiVarName+  , liftA3 (mkGeneralParamSet . pure)+      (Gen.choice [stub, asciiText])+      (Gen.list (Range.linear 0 10) $+        liftA2 (,)+          asciiText+          (Gen.maybe genExpr)+      )       Gen.bool-      (Gen.choice [stub, pure <$> asciiText])   ] + genAtom :: Gen NAtom genAtom = Gen.choice-  [ NInt   <$> Gen.integral (Range.linear 0 1000)-  , NFloat <$> Gen.float (Range.linearFrac 0.0 1000.0)+  [ NInt   <$> Gen.integral (Range.linear     0   1000  )+  , NFloat <$> Gen.float    (Range.linearFrac 0.0 1000.0)   , NBool  <$> Gen.bool   , pure NNull   ]@@ -106,48 +110,65 @@ -- list Arbitrary instance which makes the generator terminate. The -- distribution is not scientifically chosen. genExpr :: Gen NExpr-genExpr = Gen.sized $ \(Size n) -> Fix <$> if n < 2-  then Gen.choice [genConstant, genStr, genSym, genLiteralPath, genEnvPath]-  else Gen.frequency-    [ (1 , genConstant)-    , (1 , genSym)-    , (4 , Gen.resize (Size (n `div` 3)) genIf)-    , (10, genRecSet)-    , (20, genSet)-    , (5 , genList)-    , (2 , genUnary)-    , (2, Gen.resize (Size (n `div` 3)) genBinary)-    , (3, Gen.resize (Size (n `div` 3)) genSelect)-    , (20, Gen.resize (Size (n `div` 2)) genAbs)-    , (2, Gen.resize (Size (n `div` 2)) genHasAttr)-    , (10, Gen.resize (Size (n `div` 2)) genLet)-    , (10, Gen.resize (Size (n `div` 2)) genWith)-    , (1, Gen.resize (Size (n `div` 2)) genAssert)-    ]+genExpr =+  Gen.sized genCurbed  where-  genConstant    = NConstant                <$> genAtom-  genStr         = NStr                     <$> genString-  genSym         = NSym                     <$> asciiText-  genList        = NList                    <$> fairList genExpr-  genSet         = NSet NNonRecursive       <$> fairList genBinding-  genRecSet      = NSet NRecursive          <$> fairList genBinding-  genLiteralPath = NLiteralPath . ("./" <>) <$> asciiString-  genEnvPath     = NEnvPath                 <$> asciiString-  genUnary       = liftA2 NUnary   Gen.enumBounded       genExpr-  genBinary      = liftA3 NBinary  Gen.enumBounded       genExpr     genExpr-  genSelect      = liftA3 NSelect  genExpr               genAttrPath (Gen.maybe genExpr)-  genHasAttr     = liftA2 NHasAttr genExpr               genAttrPath-  genAbs         = liftA2 NAbs     genParams             genExpr-  genLet         = liftA2 NLet     (fairList genBinding) genExpr-  genIf          = liftA3 NIf      genExpr               genExpr     genExpr-  genWith        = liftA2 NWith    genExpr               genExpr-  genAssert      = liftA2 NAssert  genExpr               genExpr+  genCurbed (coerce -> n) =+    Fix <$>+      bool+        small+        big+        (n >= 2)+   where +    genConstant    = NConstant                         <$> genAtom+    genStr         = NStr                              <$> genString+    genSym         = NSym                              <$> asciiVarName+    genLiteralPath = NLiteralPath . ("./" <>) . coerce <$> asciiString+    genEnvPath     = NEnvPath . coerce                 <$> asciiString++    small = Gen.choice [genConstant, genStr, genSym, genLiteralPath, genEnvPath]++    big =+      let+          sizeDivBy i = Size $ n `div` i+          resizeDivBy i = Gen.resize (sizeDivBy i)+      in+      Gen.frequency+        [ (1 , genConstant)+        , (1 , genSym)+        , (2 , genUnary)+        , (5 , genList)+        , (20, genSet)+        , (10, genRecSet)+        , (1 , resizeDivBy 2 genAssert)+        , (4 , resizeDivBy 3 genIf)+        , (2 , resizeDivBy 3 genBinary)+        , (3 , resizeDivBy 3 genSelect)+        , (20, resizeDivBy 2 genAbs)+        , (2 , resizeDivBy 2 genHasAttr)+        , (10, resizeDivBy 2 genLet)+        , (10, resizeDivBy 2 genWith)+        ]+     where+      genList        = NList                             <$> fairList genExpr+      genSet         = NSet mempty                       <$> fairList genBinding+      genRecSet      = NSet Recursive                    <$> fairList genBinding+      genUnary       = liftA2 NUnary   Gen.enumBounded       genExpr+      genBinary      = join (liftA3 NBinary  Gen.enumBounded) genExpr+      genSelect      = liftA3 NSelect  (Gen.maybe genExpr)   genExpr     genAttrPath+      genHasAttr     = liftA2 NHasAttr genExpr               genAttrPath+      genAbs         = liftA2 NAbs     genParams             genExpr+      genLet         = liftA2 NLet     (fairList genBinding) genExpr+      genIf          = join (liftA3 NIf      genExpr) genExpr+      genWith        = join (liftA2 NWith) genExpr+      genAssert      = join (liftA2 NAssert) genExpr+ -- | Useful when there are recursive positions at each element of the list as --   it divides the size by the length of the generated list. fairList :: Gen a -> Gen [a] fairList g = Gen.sized $ \s -> do-  k <- Gen.int (Range.linear 0 (unSize s))+  k <- Gen.int $ Range.linear 0 $ unSize s   -- Use max here to avoid dividing by zero when there is the empty list   Gen.resize (Size (unSize s `div` max 1 k)) $ Gen.list (Range.singleton k) g @@ -155,49 +176,53 @@ equivUpToNormalization x y = normalize x == normalize y  normalize :: NExpr -> NExpr-normalize = foldFix $ Fix . \case+normalize = foldFix $ \case   NConstant (NInt n) | n < 0 ->-    NUnary NNeg $ Fix $ NConstant $ NInt $ negate n+    mkNeg $ mkInt $ negate n   NConstant (NFloat n) | n < 0 ->-    NUnary NNeg $ Fix $ NConstant $ NFloat $ negate n+    mkNeg $ mkFloat $ negate n -  NSet recur binds -> NSet recur $ normBinding <$> binds-  NLet binds  r -> NLet (normBinding <$> binds) r+  NSet recur binds ->+    mkSet recur $ normBinding <$> binds+  NLet binds  r ->+    mkLets (normBinding <$> binds) r -  NAbs params r -> NAbs (normParams params) r+  NAbs params r ->+    mkFunction (normParams params) r -  r             -> r+  r             -> Fix r   where   normBinding (NamedVar path r     pos) = NamedVar (normKey <$> path) r pos-  normBinding (Inherit  mr   names pos) = Inherit mr (normKey <$> names) pos+  normBinding (Inherit  mr   names pos) = Inherit mr names pos    normKey (DynamicKey quoted) = DynamicKey (normAntiquotedString quoted)   normKey (StaticKey  name  ) = StaticKey name    normAntiquotedString-    :: Antiquoted (NString NExpr) NExpr -> Antiquoted (NString NExpr) NExpr+    :: Antiquoted (NString NExpr) NExpr+    -> Antiquoted (NString NExpr) NExpr   normAntiquotedString (Plain (DoubleQuoted [EscapedNewline])) = EscapedNewline   normAntiquotedString (Plain (DoubleQuoted strs)) =-    let strs' = normAntiquotedText <$> strs-    in-    if strs == strs'-      then Plain $ DoubleQuoted strs-      else normAntiquotedString $ Plain $ DoubleQuoted strs'+    bool normAntiquotedString id (strs == strs')+      (Plain $ DoubleQuoted strs')+    where+     strs' = normAntiquotedText <$> strs   normAntiquotedString r = r -  normAntiquotedText :: Antiquoted Text NExpr -> Antiquoted Text NExpr+  normAntiquotedText+    :: Antiquoted Text NExpr+    -> Antiquoted Text NExpr   normAntiquotedText (Plain "\n"  ) = EscapedNewline   normAntiquotedText (Plain "''\n") = EscapedNewline   normAntiquotedText r              = r -  normParams (ParamSet binds var (Just "")) = ParamSet binds var mempty+  normParams (ParamSet (Just "") variadic pset) = ParamSet Nothing variadic pset   normParams r                              = r  -- | Test that parse . pretty == id up to attribute position information. prop_prettyparse :: Monad m => NExpr -> PropertyT m ()-prop_prettyparse p = do-  let prog = show $ prettyNix p+prop_prettyparse p =   either     (\ s -> do       footnote $ show $ vsep@@ -236,16 +261,18 @@         success         (equivUpToNormalization p v)     )-    (parse $ toText prog)+    (parse $ fromString prog)  where+  prog = show $ prettyNix p+   parse     = parseNixText    normalise s = String.unlines $ reverse . dropWhile isSpace . reverse <$> String.lines s    ldiff :: String -> String -> [Diff [String]]-  ldiff s1 s2 = getDiff ((: mempty) <$> String.lines s1) ((: mempty) <$> String.lines s2)+  ldiff s1 s2 = getDiff (one <$> String.lines s1) (one <$> String.lines s2)  tests :: TestLimit -> TestTree-tests n = testProperty "Pretty/Parse Property" $ withTests n $ property $ do-  x <- forAll genExpr-  prop_prettyparse x+tests n =+  testProperty "Pretty/Parse Property" $+    withTests n $ property $ prop_prettyparse =<< forAll genExpr
tests/PrettyTests.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell #-}+{-# language TemplateHaskell #-} module PrettyTests (tests) where  import           Test.Tasty@@ -9,29 +9,48 @@ import           Nix.Pretty  case_indented_antiquotation :: Assertion-case_indented_antiquotation = do-  assertPretty (mkIndentedStr 0 "echo $foo")   "''echo $foo''"-  assertPretty (mkIndentedStr 0 "echo ${foo}") "''echo ''${foo}''"+case_indented_antiquotation =+  do+    assertPretty+      (mkIndentedStr 0 "echo $foo")+      "''echo $foo''"+    assertPretty+      (mkIndentedStr 0 "echo ${foo}")+      "''echo ''${foo}''"  case_string_antiquotation :: Assertion-case_string_antiquotation = do-  assertPretty (mkStr "echo $foo")   "\"echo \\$foo\""-  assertPretty (mkStr "echo ${foo}") "\"echo \\${foo}\""+case_string_antiquotation =+  do+    assertPretty+      (mkStr "echo $foo")+      "\"echo \\$foo\""+    assertPretty+      (mkStr "echo ${foo}")+      "\"echo \\${foo}\""  case_function_params :: Assertion case_function_params =-  assertPretty (mkFunction (mkParamset mempty True) (mkInt 3)) "{ ... }:\n  3"+  assertPretty+    (mkFunction (mkVariadicParamSet mempty) (mkInt 3))+    "{ ... }:\n  3"  case_paths :: Assertion-case_paths = do-  assertPretty (mkPath False "~/test.nix") "~/test.nix"-  assertPretty (mkPath False "/test.nix")  "/test.nix"-  assertPretty (mkPath False "./test.nix") "./test.nix"+case_paths =+  do+    assertPretty+      (mkPath False "~/test.nix")+      "~/test.nix"+    assertPretty+      (mkPath False "/test.nix")+      "/test.nix"+    assertPretty+      (mkPath False "./test.nix")+      "./test.nix"  tests :: TestTree tests = $testGroupGenerator  ----------------------------------------------------------------------------------assertPretty :: NExpr -> String -> Assertion+assertPretty :: NExpr -> Text -> Assertion assertPretty e s =   assertEqual ("When pretty-printing " <> show e) s . show $ prettyNix e
tests/ReduceExprTests.hs view
@@ -1,14 +1,13 @@-{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# options_ghc -fno-warn-name-shadowing #-} module ReduceExprTests (tests) where-import           Data.Fix import           Test.Tasty import           Test.Tasty.HUnit -import           Nix.Atoms import           Nix.Expr.Types import           Nix.Expr.Types.Annotated import           Nix.Parser import           Nix.Reduce                     ( reduceExpr )+import           Nix.Expr.Shorthands   tests :: TestTree@@ -46,13 +45,13 @@ selectBasic = parseNixTextLoc "{b=2;a=42;}.a"  selectBasicExpect :: NExpr-selectBasicExpect = Fix . NConstant $ NInt 42+selectBasicExpect = mkInt 42  selectNested :: Result NExprLoc selectNested = parseNixTextLoc "{a={b=2;a=42;};b={a=2;};}.a.a"  selectNestedExpect :: NExpr-selectNestedExpect = Fix . NConstant $ NInt 42+selectNestedExpect = mkInt 42  selectIncorrectAttrPath :: Result NExprLoc selectIncorrectAttrPath = parseNixTextLoc "{a=42;}.b"
tests/TestCommon.hs view
@@ -1,32 +1,32 @@-{-# LANGUAGE PartialTypeSignatures #-}-{-# LANGUAGE ScopedTypeVariables #-}+{-# language PartialTypeSignatures #-}  module TestCommon where  import           GHC.Err                        ( errorWithoutStackTrace ) import           Control.Monad.Catch import           Data.Time+import           Data.Text.IO as Text import           Nix import           Nix.Standard import           Nix.Fresh.Basic import           System.Environment import           System.IO-import           System.Posix.Files-import           System.Posix.Temp+import           System.PosixCompat.Files+import           System.PosixCompat.Temp import           System.Process import           Test.Tasty.HUnit -hnixEvalFile :: Options -> FilePath -> IO (StdValue (StandardT (StdIdT IO)))+hnixEvalFile :: Options -> Path -> IO (StdValue (StandardT (StdIdT IO))) hnixEvalFile opts file =   do     parseResult <- parseNixFileLoc file     either-      (\ err -> fail $ "Parsing failed for file `" <> file <> "`.\n" <> show err)+      (\ err -> fail $ "Parsing failed for file `" <> coerce file <> "`.\n" <> show err)       (\ expr ->         do           setEnv "TEST_VAR" "foo"           runWithBasicEffects opts $-            catch (evaluateExpression (pure file) nixEvalExprLoc normalForm expr) $+            catch (evaluateExpression (pure $ coerce file) nixEvalExprLoc normalForm expr) $             \case               NixException frames ->                 errorWithoutStackTrace . show@@ -46,30 +46,31 @@     )     (parseNixText src) -nixEvalString :: String -> IO String-nixEvalString expr = do-  (fp, h) <- mkstemp "nix-test-eval"-  hPutStr h expr-  hClose h-  res <- nixEvalFile fp-  removeLink fp-  pure res+nixEvalString :: Text -> IO Text+nixEvalString expr =+  do+    (coerce -> fp, h) <- mkstemp "nix-test-eval"+    Text.hPutStr h expr+    hClose h+    res <- nixEvalFile fp+    removeLink $ coerce fp+    pure res -nixEvalFile :: FilePath -> IO String-nixEvalFile fp = readProcess "nix-instantiate" ["--eval", "--strict", fp] ""+nixEvalFile :: Path -> IO Text+nixEvalFile fp = fromString <$> readProcess "nix-instantiate" ["--eval", "--strict", coerce fp] mempty -assertEvalFileMatchesNix :: FilePath -> Assertion-assertEvalFileMatchesNix fp = do-  time    <- liftIO getCurrentTime-  hnixVal <- (<> "\n") . printNix <$> hnixEvalFile (defaultOptions time) fp-  nixVal  <- nixEvalFile fp-  assertEqual fp nixVal hnixVal+assertEvalFileMatchesNix :: Path -> Assertion+assertEvalFileMatchesNix fp =+  do+    time    <- liftIO getCurrentTime+    hnixVal <- (<> "\n") . printNix <$> hnixEvalFile (defaultOptions time) fp+    nixVal  <- nixEvalFile fp+    assertEqual (coerce fp) nixVal hnixVal  assertEvalMatchesNix :: Text -> Assertion-assertEvalMatchesNix expr = do-  time    <- liftIO getCurrentTime-  hnixVal <- (<> "\n") . printNix <$> hnixEvalText (defaultOptions time) expr-  nixVal  <- nixEvalString expr'-  assertEqual expr' nixVal hnixVal- where-  expr' = toString expr+assertEvalMatchesNix expr =+  do+    time    <- liftIO getCurrentTime+    hnixVal <- (<> "\n") . printNix <$> hnixEvalText (defaultOptions time) expr+    nixVal  <- nixEvalString expr+    assertEqual (toString expr) nixVal hnixVal