Skip to content

Commit 5dc09e9

Browse files
#1005: coercion to NixString; iterNValue': flip 1st arg; unflip runFreshIdT
PR is interesting in `Utils` & `Value` where things were updated to fixpoint combinators. Which, if internally laziness is preserved - running the function & apply the argument to it only once & optimize during compilation. In Haskell Core I found that `fix` sometimes roughly converts just to `let x = f x in x` (stays a basic `let`, `letrec` in terms of Core language). So far I can not reason beyond Core, it is hard to say how `letrec` compiles. This is a work I did before the `Nix 2.4` release, which broke the CI on all fronts. I decided to not run putting created by upstream fires. Decided to not overcomplicate the Git processes for myself, so decided to finish & contribute the work first & then go do fix things.
2 parents b4deb39 + 2a38563 commit 5dc09e9

File tree

19 files changed

+307
-262
lines changed

19 files changed

+307
-262
lines changed

main/Main.hs

Lines changed: 75 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import qualified Data.Text.IO as Text
1919
import Text.Show.Pretty ( ppShow )
2020
import Nix hiding ( force )
2121
import Nix.Convert
22-
import Nix.Fresh.Basic
2322
import Nix.Json
2423
import Nix.Options.Parser
2524
import Nix.Standard
@@ -47,16 +46,16 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
4746
where
4847
-- 2021-07-15: NOTE: This logic should be weaved stronger through CLI options logic (OptParse-Applicative code)
4948
-- As this logic is not stated in the CLI documentation, for example. So user has no knowledge of these.
50-
execContentsFilesOrRepl :: StandardT (StdIdT IO) ()
49+
execContentsFilesOrRepl :: StdIO
5150
execContentsFilesOrRepl =
5251
fromMaybe
5352
loadFromCliFilePathList
54-
( loadBinaryCacheFile <|>
53+
$ loadBinaryCacheFile <|>
5554
loadLiteralExpression <|>
5655
loadExpressionFromFile
57-
)
5856
where
5957
-- | The base case: read expressions from the last CLI directive (@[FILE]@) listed on the command line.
58+
loadFromCliFilePathList :: StdIO
6059
loadFromCliFilePathList =
6160
case filePaths of
6261
[] -> runRepl
@@ -67,27 +66,28 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
6766
runRepl = withEmptyNixContext Repl.main
6867

6968
readExpressionFromStdin =
70-
do
71-
expr <- liftIO Text.getContents
72-
processExpr expr
69+
processExpr =<< liftIO Text.getContents
7370

74-
processSeveralFiles :: [Path] -> StandardT (StdIdT IO) ()
71+
processSeveralFiles :: [Path] -> StdIO
7572
processSeveralFiles = traverse_ processFile
7673
where
7774
processFile path = handleResult (pure path) =<< parseNixFileLoc path
7875

7976
-- | The `--read` option: load expression from a serialized file.
77+
loadBinaryCacheFile :: Maybe StdIO
8078
loadBinaryCacheFile =
8179
(\ (binaryCacheFile :: Path) ->
8280
do
8381
let file = replaceExtension binaryCacheFile "nixc"
84-
processCLIOptions (Just file) =<< liftIO (readCache binaryCacheFile)
82+
processCLIOptions (pure file) =<< liftIO (readCache binaryCacheFile)
8583
) <$> readFrom
8684

8785
-- | The `--expr` option: read expression from the argument string
86+
loadLiteralExpression :: Maybe StdIO
8887
loadLiteralExpression = processExpr <$> expression
8988

9089
-- | The `--file` argument: read expressions from the files listed in the argument file
90+
loadExpressionFromFile :: Maybe StdIO
9191
loadExpressionFromFile =
9292
-- We can start use Text as in the base case, requires changing Path -> Text
9393
-- But that is a gradual process:
@@ -98,7 +98,8 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
9898
_fp -> readFile _fp
9999
) <$> fromFile
100100

101-
processExpr text = handleResult Nothing $ parseNixTextLoc text
101+
processExpr :: Text -> StdIO
102+
processExpr = handleResult mempty . parseNixTextLoc
102103

103104
withEmptyNixContext = withNixContext mempty
104105

@@ -120,10 +121,10 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
120121
expr' <- liftIO $ reduceExpr mpath expr
121122
either
122123
(\ err -> errorWithoutStackTrace $ "Type error: " <> ppShow err)
123-
(\ ty -> liftIO $ putStrLn $ "Type of expression: " <>
124-
ppShow (maybeToMonoid $ Map.lookup @VarName @[Scheme] "it" $ coerce ty)
124+
(liftIO . putStrLn . (<>) "Type of expression: " .
125+
ppShow . maybeToMonoid . Map.lookup @VarName @[Scheme] "it" . coerce
125126
)
126-
(HM.inferTop mempty (one ("it", stripAnnotation expr')))
127+
$ HM.inferTop mempty $ curry one "it" $ stripAnnotation expr'
127128

128129
-- liftIO $ putStrLn $ runST $
129130
-- runLintM opts . renderSymbolic =<< lint opts expr
@@ -133,23 +134,20 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
133134
NixException frames ->
134135
errorWithoutStackTrace . show =<<
135136
renderFrames
136-
@(StdValue (StandardT (StdIdT IO)))
137-
@(StdThunk (StandardT (StdIdT IO)))
137+
@StdVal
138+
@StdThun
138139
frames
139140

140141
when repl $
141142
withEmptyNixContext $
142143
bool
143144
Repl.main
144-
(do
145-
val <- nixEvalExprLoc (coerce mpath) expr
146-
Repl.main' $ pure val
147-
)
145+
((Repl.main' . pure) =<< nixEvalExprLoc (coerce mpath) expr)
148146
evaluate
149147
)
150148

151149
-- 2021-07-15: NOTE: Logic of CLI Option processing is scattered over several functions, needs to be consolicated.
152-
processCLIOptions :: Maybe Path -> NExprLoc -> StandardT (StdIdT IO) ()
150+
processCLIOptions :: Maybe Path -> NExprLoc -> StdIO
153151
processCLIOptions mpath expr
154152
| evaluate =
155153
if
@@ -174,37 +172,57 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
174172
evaluateExprWithEvaluator evaluator = evaluateExpression (coerce mpath) evaluator printer
175173

176174
printer
177-
| finder = findAttrs <=< fromValue @(AttrSet (StdValue (StandardT (StdIdT IO))))
175+
:: StdVal
176+
-> StdIO
177+
printer
178+
| finder = findAttrs <=< fromValue @(AttrSet StdVal)
178179
| otherwise = printer'
179180
where
180181
printer'
181-
| xml = go (stringIgnoreContext . toXML) normalForm
182+
| xml = fun (stringIgnoreContext . toXML) normalForm
182183
-- 2021-05-27: NOTE: With naive fix of the #941
183184
-- This is overall a naive printer implementation, as options should interact/respect one another.
184185
-- A nice question: "Should respect one another to what degree?": Go full combinator way, for which
185186
-- old Nix CLI is nototrious for (and that would mean to reimplement the old Nix CLI),
186187
-- OR: https://github.com/haskell-nix/hnix/issues/172 and have some sane standart/default behaviour for (most) keys.
187-
| json = go (stringIgnoreContext . mempty . nvalueToJSONNixString) normalForm
188-
| strict = go (show . prettyNValue) normalForm
189-
| values = go (show . prettyNValueProv) removeEffects
190-
| otherwise = go (show . prettyNValue) removeEffects
188+
| json = fun (stringIgnoreContext . mempty . nvalueToJSONNixString) normalForm
189+
| strict = fun (show . prettyNValue) normalForm
190+
| values = fun (show . prettyNValueProv) removeEffects
191+
| otherwise = fun (show . prettyNValue) removeEffects
191192
where
192-
go
193+
fun
193194
:: (b -> Text)
194-
-> (a -> StandardT (StdIdT IO) b)
195+
-> (a -> StandardIO b)
195196
-> a
196-
-> StandardT (StdIdT IO) ()
197-
go g f = liftIO . Text.putStrLn . g <=< f
197+
-> StdIO
198+
fun g f = liftIO . Text.putStrLn . g <=< f
198199

199200
findAttrs
200-
:: AttrSet (StdValue (StandardT (StdIdT IO)))
201-
-> StandardT (StdIdT IO) ()
201+
:: AttrSet StdVal
202+
-> StdIO
202203
findAttrs = go mempty
203204
where
205+
go :: Text -> AttrSet StdVal -> StdIO
204206
go prefix s =
205-
do
206-
xs <-
207-
traverse
207+
traverse_
208+
(\ (k, mv) ->
209+
do
210+
let
211+
path = prefix <> k
212+
(report, descend) = filterEntry path k
213+
when report $
214+
do
215+
liftIO $ Text.putStrLn path
216+
when descend $
217+
maybe
218+
stub
219+
(\case
220+
NVSet _ s' -> go (path <> ".") s'
221+
_ -> stub
222+
)
223+
mv
224+
)
225+
=<< traverse
208226
(\ (k, nv) ->
209227
(k, ) <$>
210228
free
@@ -214,12 +232,12 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
214232
path = prefix <> k
215233
(_, descend) = filterEntry path k
216234

217-
val <- readRef @(StandardT (StdIdT IO)) ref
235+
val <- readRef @StandardIO ref
218236
bool
219237
(pure Nothing)
220238
(forceEntry path nv)
221239
(descend &&
222-
deferred
240+
deferred
223241
(const False)
224242
(const True)
225243
val
@@ -229,25 +247,6 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
229247
nv
230248
)
231249
(sortWith fst $ M.toList $ M.mapKeys coerce s)
232-
traverse_
233-
(\ (k, mv) ->
234-
do
235-
let
236-
path = prefix <> k
237-
(report, descend) = filterEntry path k
238-
when report $
239-
do
240-
liftIO $ Text.putStrLn path
241-
when descend $
242-
maybe
243-
stub
244-
(\case
245-
NVSet _ s' -> go (path <> ".") s'
246-
_ -> stub
247-
)
248-
mv
249-
)
250-
xs
251250
where
252251
filterEntry path k = case (path, k) of
253252
("stdenv", "stdenv" ) -> (True , True )
@@ -267,36 +266,37 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl
267266
_ -> (True , True )
268267

269268
forceEntry
270-
:: MonadValue a (StandardT (StdIdT IO))
269+
:: MonadValue a StandardIO
271270
=> Text
272271
-> a
273-
-> StandardT (StdIdT IO) (Maybe a)
272+
-> StandardIO (Maybe a)
274273
forceEntry k v =
275274
catch
276275
(pure <$> demand v)
277-
(\ (NixException frames) ->
278-
do
279-
liftIO
280-
. Text.putStrLn
281-
. (("Exception forcing " <> k <> ": ") <>)
282-
. show =<<
283-
renderFrames
284-
@(StdValue (StandardT (StdIdT IO)))
285-
@(StdThunk (StandardT (StdIdT IO)))
286-
frames
287-
pure Nothing
288-
)
276+
fun
277+
where
278+
fun :: NixException -> StandardIO (Maybe a)
279+
fun (coerce -> frames) =
280+
do
281+
liftIO
282+
. Text.putStrLn
283+
. (("Exception forcing " <> k <> ": ") <>)
284+
. show =<<
285+
renderFrames
286+
@StdVal
287+
@StdThun
288+
frames
289+
pure Nothing
289290

290291
reduction path mpathToContext annExpr =
291292
do
292293
eres <-
293294
withNixContext
294295
mpathToContext
295-
(reducingEvalExpr
296-
evalContent
297-
mpathToContext
298-
annExpr
299-
)
296+
$ reducingEvalExpr
297+
evalContent
298+
mpathToContext
299+
annExpr
300300
handleReduced path eres
301301

302302
handleReduced

src/Nix/Atoms.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Data.Binary ( Binary )
1111
import Data.Aeson.Types ( FromJSON
1212
, ToJSON
1313
)
14-
-- 2021-08-01: NOTE: Check the order efficience of NAtom constructors.
14+
-- 2021-08-01: NOTE: Check the order effectiveness of NAtom constructors.
1515

1616
-- | Atoms are values that evaluate to themselves.
1717
-- In other words - this is a constructors that are literals in Nix.

src/Nix/Builtins.hs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ nixPathNix =
447447
<> rest
448448

449449
toStringNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
450-
toStringNix = toValue <=< coerceToString callFunc DontCopyToStore CoerceAny
450+
toStringNix = toValue <=< coerceAnyToNixString callFunc DontCopyToStore
451451

452452
hasAttrNix
453453
:: forall e t f m
@@ -825,7 +825,7 @@ catAttrsNix attrName xs =
825825
baseNameOfNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
826826
baseNameOfNix x =
827827
do
828-
ns <- coerceToString callFunc DontCopyToStore CoerceStringy x
828+
ns <- coerceStringlikeToNixString DontCopyToStore x
829829
pure $
830830
nvStr $
831831
modifyNixContents
@@ -1208,11 +1208,9 @@ isFunctionNix nv =
12081208
_ -> False
12091209

12101210
throwNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
1211-
throwNix mnv =
1212-
do
1213-
ns <- coerceToString callFunc CopyToStore CoerceStringy mnv
1214-
1215-
throwError . ErrorCall . toString $ stringIgnoreContext ns
1211+
throwNix =
1212+
throwError . ErrorCall . toString . stringIgnoreContext
1213+
<=< coerceStringlikeToNixString CopyToStore
12161214

12171215
-- | Implementation of Nix @import@ clause.
12181216
--
@@ -1628,12 +1626,11 @@ execNix
16281626
:: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)
16291627
execNix xs =
16301628
do
1631-
ls <- fromValue @[NValue t f m] xs
1632-
xs <- traverse (coerceToString callFunc DontCopyToStore CoerceStringy) ls
1629+
xs' <- traverse (coerceStringlikeToNixString DontCopyToStore) =<< fromValue @[NValue t f m] xs
16331630
-- 2018-11-19: NOTE: Still need to do something with the context here
16341631
-- See prim_exec in nix/src/libexpr/primops.cc
16351632
-- Requires the implementation of EvalState::realiseContext
1636-
exec $ stringIgnoreContext <$> xs
1633+
exec $ stringIgnoreContext <$> xs'
16371634

16381635
fetchurlNix
16391636
:: forall e t f m . MonadNix e t f m => NValue t f m -> m (NValue t f m)

src/Nix/Effects.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,8 @@ addTextToStore a b c d =
432432
pure
433433
=<< addTextToStore' a b c d
434434

435+
-- 2021-10-30: NOTE: Misleading name, please rename.
436+
-- | Add @Path@ into the Nix Store
435437
addPath :: (Framed e m, MonadStore m) => Path -> m StorePath
436438
addPath p =
437439
either

src/Nix/Effects/Derivation.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,9 @@ defaultDerivationStrict val = do
309309
toStorePaths = foldl (flip addToInputs) mempty
310310

311311
addToInputs :: Bifunctor p => StringContext -> p (Set Text) (Map Text [Text]) -> p (Set Text) (Map Text [Text])
312-
addToInputs (StringContext path kind) = case kind of
313-
DirectPath -> first (Set.insert (coerce path))
314-
DerivationOutput o -> second (Map.insertWith (<>) (coerce path) $ one o)
312+
addToInputs (StringContext (coerce -> path) kind) = case kind of
313+
DirectPath -> first $ Set.insert path
314+
DerivationOutput o -> second $ Map.insertWith (<>) path $ one o
315315
AllOutputs ->
316316
-- TODO: recursive lookup. See prim_derivationStrict
317317
-- XXX: When is this really used ?
@@ -372,7 +372,7 @@ buildDerivationWithContext drvAttrs = do
372372
rawString :: Text <- extractNixString jsonString
373373
pure $ one ("__json", rawString)
374374
else
375-
traverse (extractNixString <=< lift . coerceToString callFunc CopyToStore CoerceAny) $
375+
traverse (extractNixString <=< lift . coerceAnyToNixString callFunc CopyToStore) $
376376
Map.fromList $ M.toList $ deleteKeys [ "args", "__ignoreNulls" ] attrs
377377

378378
pure $ Derivation { platform, builder, args, env, hashMode, useJson

src/Nix/Eval.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ framedEvalExprLoc
565565
framedEvalExprLoc =
566566
adi addMetaInfo evalContent
567567

568-
-- | Add source postionss & frame context system.
568+
-- | Add source positions & frame context system.
569569
addMetaInfo
570570
:: forall v m e a
571571
. (Framed e m, Scoped v m, Has e SrcSpan, Typeable m, Typeable v)

0 commit comments

Comments
 (0)