Skip to content

Commit 73d2134

Browse files
committed
Improvements to make it easier to implement runners other than StandardT
* Refactor MonadThunk * Refactor Nix.Thunk.Basic * Add Nix.Thunk.Separate * Add Nix.Fresh.Stable * Add StableId * Remove Scopes from Context and replace with ScopeT * Remove the `t` parameter formerly representing thunks. It can now be inferred from `m` TODO: * [ ] Provide implementations for citations class * [ ] Restore Nix.Lint * [ ] Fix 3 broken tests
1 parent fccb886 commit 73d2134

39 files changed

+1610
-1110
lines changed

hnix.cabal

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,9 @@ library
362362
Nix.Frames
363363
Nix.Fresh
364364
Nix.Fresh.Basic
365+
Nix.Fresh.Stable
365366
Nix.Json
366-
Nix.Lint
367+
-- Nix.Lint
367368
Nix.Normal
368369
Nix.Options
369370
Nix.Parser
@@ -372,12 +373,14 @@ library
372373
Nix.Render
373374
Nix.Render.Frame
374375
Nix.Scope
376+
Nix.Scope.Basic
375377
Nix.Standard
376378
Nix.String
377379
Nix.String.Coerce
378380
Nix.TH
379381
Nix.Thunk
380382
Nix.Thunk.Basic
383+
Nix.Thunk.StableId
381384
Nix.Type.Assumption
382385
Nix.Type.Env
383386
Nix.Type.Infer
@@ -406,11 +409,13 @@ library
406409
, deepseq >= 1.4.3 && <1.5
407410
, deriving-compat >= 0.3 && < 0.6
408411
, directory >= 1.3.1 && < 1.4
412+
, exception-transformers >= 0.4 && <0.5
409413
, exceptions >= 0.10.0 && < 0.11
410414
, filepath >= 1.4.2 && < 1.5
411415
, free >= 5.1 && < 5.2
412416
, gitrev >= 1.1.0 && < 1.4
413417
, hashable >= 1.2.5 && < 1.4
418+
, ghc-prim >= 0.5 && <0.7
414419
, hashing >= 0.1.0 && < 0.2
415420
, hnix-store-core >= 0.4.0 && < 0.5
416421
, hnix-store-remote >= 0.4.0 && < 0.5

main/Main.hs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ import qualified Data.Text.IO as Text
2626
import Nix
2727
import Nix.Convert
2828
import qualified Nix.Eval as Eval
29-
import Nix.Fresh.Basic
29+
import Nix.Fresh.Stable
3030
import Nix.Json
3131
import Nix.Options.Parser
3232
import Nix.Standard
3333
import Nix.Thunk.Basic
3434
import qualified Nix.Type.Env as Env
3535
import qualified Nix.Type.Infer as HM
3636
import Nix.Utils
37+
import Nix.Utils.Fix1
3738
import Nix.Var
3839
import Nix.Value.Monad
3940
import Options.Applicative hiding ( ParserResult(..) )
@@ -94,8 +95,9 @@ main = do
9495
NixException frames ->
9596
errorWithoutStackTrace
9697
. show
97-
=<< renderFrames @(StdValue (StandardT (StdIdT IO)))
98-
@(StdThunk (StandardT (StdIdT IO)))
98+
=<< renderFrames
99+
@(StdValue (StandardT IO))
100+
@(StdThunk (StandardT IO) IO)
99101
frames
100102

101103
when (repl opts) $
@@ -138,7 +140,7 @@ main = do
138140
where
139141
printer
140142
| finder opts
141-
= fromValue @(AttrSet (StdValue (StandardT (StdIdT IO)))) >=> findAttrs
143+
= fromValue @(AttrSet (StdValue (StandardT IO))) >=> findAttrs
142144
| xml opts
143145
= liftIO
144146
. putStrLn
@@ -159,17 +161,17 @@ main = do
159161
= liftIO . print . prettyNValue <=< removeEffects
160162
where
161163
findAttrs
162-
:: AttrSet (StdValue (StandardT (StdIdT IO)))
163-
-> StandardT (StdIdT IO) ()
164+
:: AttrSet (StdValue (StandardT IO))
165+
-> StandardT IO ()
164166
findAttrs = go ""
165167
where
166168
go prefix s = do
167169
xs <- forM (sortOn fst (M.toList s)) $ \(k, nv) -> case nv of
168170
Free v -> pure (k, Just (Free v))
169-
Pure (StdThunk (extract -> Thunk _ _ ref)) -> do
171+
Pure (StdThunk (Thunk _ _ ref)) -> do
170172
let path = prefix ++ Text.unpack k
171173
(_, descend) = filterEntry path k
172-
val <- readVar @(StandardT (StdIdT IO)) ref
174+
val <- readVar @(StandardT IO) ref
173175
case val of
174176
Computed _ -> pure (k, Nothing)
175177
_ | descend -> (k, ) <$> forceEntry path nv
@@ -211,8 +213,9 @@ main = do
211213
. (k ++)
212214
. (": " ++)
213215
. show
214-
=<< renderFrames @(StdValue (StandardT (StdIdT IO)))
215-
@(StdThunk (StandardT (StdIdT IO)))
216+
=<< renderFrames
217+
@(StdValue (StandardT IO))
218+
@(StdThunk (StandardT IO) IO)
216219
frames
217220
pure Nothing
218221

@@ -224,8 +227,8 @@ main = do
224227
handleReduced
225228
:: (MonadThrow m, MonadIO m)
226229
=> FilePath
227-
-> (NExprLoc, Either SomeException (NValue t f m))
228-
-> m (NValue t f m)
230+
-> (NExprLoc, Either SomeException (NValue f m))
231+
-> m (NValue f m)
229232
handleReduced path (expr', eres) = do
230233
liftIO $ do
231234
putStrLn $ "Wrote winnowed expression tree to " ++ path

main/Repl.hs

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
{-# LANGUAGE LambdaCase #-}
1111
{-# LANGUAGE FlexibleContexts #-}
1212
{-# LANGUAGE FlexibleInstances #-}
13+
{-# LANGUAGE GADTs #-}
1314
{-# LANGUAGE MultiWayIf #-}
1415
{-# LANGUAGE CPP #-}
1516
{-# LANGUAGE OverloadedStrings #-}
1617
{-# LANGUAGE ScopedTypeVariables #-}
18+
{-# LANGUAGE StandaloneDeriving #-}
1719
{-# LANGUAGE TupleSections #-}
1820
{-# LANGUAGE TypeApplications #-}
21+
{-# LANGUAGE UndecidableInstances #-}
1922

2023
module Repl
2124
( main
@@ -29,6 +32,8 @@ import Nix.Scope
2932
import Nix.Utils
3033
import Nix.Value.Monad (demand)
3134

35+
import Control.Comonad
36+
import Data.Functor.Classes
3237
import qualified Data.List
3338
import qualified Data.Maybe
3439
import qualified Data.HashMap.Lazy
@@ -64,13 +69,13 @@ import qualified System.Exit
6469
import qualified System.IO.Error
6570

6671
-- | Repl entry point
67-
main :: (MonadNix e t f m, MonadIO m, MonadMask m) => m ()
72+
main :: (MonadNix e f m, MonadIO m, MonadMask m) => m ()
6873
main = main' Nothing
6974

7075
-- | Principled version allowing to pass initial value for context.
7176
--
7277
-- Passed value is stored in context with "input" key.
73-
main' :: (MonadNix e t f m, MonadIO m, MonadMask m) => Maybe (NValue t f m) -> m ()
78+
main' :: (MonadNix e f m, MonadIO m, MonadMask m) => Maybe (NValue f m) -> m ()
7479
main' iniVal = initState iniVal >>= \s -> flip evalStateT s
7580
$ System.Console.Repline.evalRepl
7681
banner
@@ -128,11 +133,14 @@ main' iniVal = initState iniVal >>= \s -> flip evalStateT s
128133
-- * Types
129134
---------------------------------------------------------------------------------
130135

131-
data IState t f m = IState
136+
data IState f m = IState
132137
{ replIt :: Maybe NExprLoc -- ^ Last expression entered
133-
, replCtx :: AttrSet (NValue t f m) -- ^ Value environment
138+
, replCtx :: AttrSet (NValue f m) -- ^ Value environment
134139
, replCfg :: ReplConfig -- ^ REPL configuration
135-
} deriving (Eq, Show)
140+
}
141+
142+
deriving instance (Eq1 f, Eq1 m, Eq (Thunk m)) => Eq (IState f m)
143+
deriving instance (Comonad f, Show (Thunk m)) => Show (IState f m)
136144

137145
data ReplConfig = ReplConfig
138146
{ cfgDebug :: Bool
@@ -148,7 +156,7 @@ defReplConfig = ReplConfig
148156
}
149157

150158
-- | Create initial IState for REPL
151-
initState :: MonadNix e t f m => Maybe (NValue t f m) -> m (IState t f m)
159+
initState :: MonadNix e f m => Maybe (NValue f m) -> m (IState f m)
152160
initState mIni = do
153161

154162
builtins <- evalText "builtins"
@@ -164,23 +172,23 @@ initState mIni = do
164172
, cfgValues = values opts
165173
}
166174
where
167-
evalText :: (MonadNix e t f m) => Text -> m (NValue t f m)
175+
evalText :: (MonadNix e f m) => Text -> m (NValue f m)
168176
evalText expr = case parseNixTextLoc expr of
169177
Failure e -> error $ "Impossible happened: Unable to parse expression - '" ++ Data.Text.unpack expr ++ "' error was " ++ show e
170178
Success e -> do evalExprLoc e
171179

172-
type Repl e t f m = HaskelineT (StateT (IState t f m) m)
180+
type Repl e f m = HaskelineT (StateT (IState f m) m)
173181

174182
---------------------------------------------------------------------------------
175183
-- * Execution
176184
---------------------------------------------------------------------------------
177185

178186
exec
179-
:: forall e t f m
180-
. (MonadNix e t f m, MonadIO m)
187+
:: forall e f m
188+
. (MonadNix e f m, MonadIO m)
181189
=> Bool
182190
-> Text
183-
-> Repl e t f m (Maybe (NValue t f m))
191+
-> Repl e f m (Maybe (NValue f m))
184192
exec update source = do
185193
-- Get the current interpreter state
186194
st <- get
@@ -206,7 +214,7 @@ exec update source = do
206214

207215
case mVal of
208216
Left (NixException frames) -> do
209-
lift $ lift $ liftIO . print =<< renderFrames @(NValue t f m) @t frames
217+
lift $ lift $ liftIO . print =<< renderFrames @(NValue f m) frames
210218
pure Nothing
211219
Right val -> do
212220
-- Update the interpreter state
@@ -237,18 +245,18 @@ exec update source = do
237245
toAttrSet i = "{" <> i <> (if Data.Text.isSuffixOf ";" i then mempty else ";") <> "}"
238246

239247
cmd
240-
:: (MonadNix e t f m, MonadIO m)
248+
:: (MonadNix e f m, MonadIO m)
241249
=> String
242-
-> Repl e t f m ()
250+
-> Repl e f m ()
243251
cmd source = do
244252
mVal <- exec True (Data.Text.pack source)
245253
case mVal of
246254
Nothing -> pure ()
247255
Just val -> printValue val
248256

249-
printValue :: (MonadNix e t f m, MonadIO m)
250-
=> NValue t f m
251-
-> Repl e t f m ()
257+
printValue :: (MonadNix e f m, MonadIO m)
258+
=> NValue f m
259+
-> Repl e f m ()
252260
printValue val = do
253261
cfg <- replCfg <$> get
254262
lift $ lift $ do
@@ -262,9 +270,9 @@ printValue val = do
262270
---------------------------------------------------------------------------------
263271

264272
-- :browse command
265-
browse :: (MonadNix e t f m, MonadIO m)
273+
browse :: (MonadNix e f m, MonadIO m)
266274
=> String
267-
-> Repl e t f m ()
275+
-> Repl e f m ()
268276
browse _ = do
269277
st <- get
270278
forM_ (Data.HashMap.Lazy.toList $ replCtx st) $ \(k, v) -> do
@@ -273,9 +281,9 @@ browse _ = do
273281

274282
-- :load command
275283
load
276-
:: (MonadNix e t f m, MonadIO m)
284+
:: (MonadNix e f m, MonadIO m)
277285
=> String
278-
-> Repl e t f m ()
286+
-> Repl e f m ()
279287
load args = do
280288
contents <- liftIO
281289
$ Data.Text.IO.readFile
@@ -286,9 +294,9 @@ load args = do
286294

287295
-- :type command
288296
typeof
289-
:: (MonadNix e t f m, MonadIO m)
297+
:: (MonadNix e f m, MonadIO m)
290298
=> String
291-
-> Repl e t f m ()
299+
-> Repl e f m ()
292300
typeof args = do
293301
st <- get
294302
mVal <- case Data.HashMap.Lazy.lookup line (replCtx st) of
@@ -303,11 +311,11 @@ typeof args = do
303311
where line = Data.Text.pack args
304312

305313
-- :quit command
306-
quit :: (MonadNix e t f m, MonadIO m) => a -> Repl e t f m ()
314+
quit :: (MonadNix e f m, MonadIO m) => a -> Repl e f m ()
307315
quit _ = liftIO System.Exit.exitSuccess
308316

309317
-- :set command
310-
setConfig :: (MonadNix e t f m, MonadIO m) => String -> Repl e t f m ()
318+
setConfig :: (MonadNix e f m, MonadIO m) => String -> Repl e f m ()
311319
setConfig args = case words args of
312320
[] -> liftIO $ putStrLn "No option to set specified"
313321
(x:_xs) ->
@@ -326,8 +334,8 @@ defaultMatcher =
326334
]
327335

328336
completion
329-
:: (MonadNix e t f m, MonadIO m)
330-
=> CompleterStyle (StateT (IState t f m) m)
337+
:: (MonadNix e f m, MonadIO m)
338+
=> CompleterStyle (StateT (IState f m) m)
331339
completion = System.Console.Repline.Prefix
332340
(completeWordWithPrev (Just '\\') separators completeFunc)
333341
defaultMatcher
@@ -340,15 +348,15 @@ completion = System.Console.Repline.Prefix
340348
-- Heavily inspired by Dhall Repl, with `algebraicComplete`
341349
-- adjusted to monadic variant able to `demand` thunks.
342350
completeFunc
343-
:: forall e t f m . (MonadNix e t f m, MonadIO m)
351+
:: forall e f m . (MonadNix e f m, MonadIO m)
344352
=> String
345353
-> String
346-
-> (StateT (IState t f m) m) [Completion]
354+
-> (StateT (IState f m) m) [Completion]
347355
completeFunc reversedPrev word
348356
-- Commands
349357
| reversedPrev == ":"
350358
= pure . listCompletion
351-
$ fmap helpOptionName (helpOptions :: HelpOptions e t f m)
359+
$ fmap helpOptionName (helpOptions :: HelpOptions e f m)
352360

353361
-- Files
354362
| any (`Data.List.isPrefixOf` word) [ "/", "./", "../", "~/" ]
@@ -383,9 +391,9 @@ completeFunc reversedPrev word
383391

384392
notFinished x = x { isFinished = False }
385393

386-
algebraicComplete :: (MonadNix e t f m)
394+
algebraicComplete :: (MonadNix e f m)
387395
=> [Text]
388-
-> NValue t f m
396+
-> NValue f m
389397
-> m [Text]
390398
algebraicComplete subFields val =
391399
let keys = fmap ("." <>) . Data.HashMap.Lazy.keys
@@ -407,16 +415,16 @@ completeFunc reversedPrev word
407415

408416
-- HelpOption inspired by Dhall Repl
409417
-- with `Doc` instead of String for syntax and doc
410-
data HelpOption e t f m = HelpOption
418+
data HelpOption e f m = HelpOption
411419
{ helpOptionName :: String
412420
, helpOptionSyntax :: Doc ()
413421
, helpOptionDoc :: Doc ()
414-
, helpOptionFunction :: Cmd (Repl e t f m)
422+
, helpOptionFunction :: Cmd (Repl e f m)
415423
}
416424

417-
type HelpOptions e t f m = [HelpOption e t f m]
425+
type HelpOptions e f m = [HelpOption e f m]
418426

419-
helpOptions :: (MonadNix e t f m, MonadIO m) => HelpOptions e t f m
427+
helpOptions :: (MonadNix e f m, MonadIO m) => HelpOptions e f m
420428
helpOptions =
421429
[ HelpOption
422430
"help"
@@ -513,10 +521,10 @@ renderSetOptions so =
513521
<> Prettyprinter.line
514522
<> Prettyprinter.indent 4 (helpSetOptionDoc h)
515523

516-
help :: (MonadNix e t f m, MonadIO m)
517-
=> HelpOptions e t f m
524+
help :: (MonadNix e f m, MonadIO m)
525+
=> HelpOptions e f m
518526
-> String
519-
-> Repl e t f m ()
527+
-> Repl e f m ()
520528
help hs _ = do
521529
liftIO $ putStrLn "Available commands:\n"
522530
forM_ hs $ \h ->
@@ -532,6 +540,6 @@ help hs _ = do
532540
<> Prettyprinter.indent 4 (helpOptionDoc h)
533541

534542
options
535-
:: (MonadNix e t f m, MonadIO m)
536-
=> System.Console.Repline.Options (Repl e t f m)
543+
:: (MonadNix e f m, MonadIO m)
544+
=> System.Console.Repline.Options (Repl e f m)
537545
options = (\h -> (helpOptionName h, helpOptionFunction h)) <$> helpOptions

0 commit comments

Comments
 (0)