Skip to content

Commit 36802ae

Browse files
Merge #886 Harmonize NValue and NValue' notations; help GHC with patterns by COMPLETE annotations.
2 parents 2555ffe + 00a7f21 commit 36802ae

File tree

9 files changed

+103
-40
lines changed

9 files changed

+103
-40
lines changed

ChangeLog.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,11 @@
137137
MonadPaths (Fix1 t) :: Nix.Standard -> Nix.Effects
138138
MonadPutStr (Fix1 t) :: Nix.Standard -> Nix.Effects
139139
```
140-
* [(link)](https://github.com/haskell-nix/hnix/pull/878/files) `nvSet{,',P}`: got unflipped, now accept source position argument before the value.
140+
* [(link)](https://github.com/haskell-nix/hnix/pull/878/files) `Nix.Value`: `nvSet{,',P}`: got unflipped, now accept source position argument before the value.
141141

142-
* [(link)](https://github.com/haskell-nix/hnix/pull/878/files) `mkNixDoc`: got unflipped.
142+
* [(link)](https://github.com/haskell-nix/hnix/pull/878/files) `Nix.Pretty`: `mkNixDoc`: got unflipped.
143+
144+
* [(link)](https://github.com/haskell-nix/hnix/pull/886/commits/381b0e5df9cc620a25533ff1c84045a4ea37a833) `Nix.Value`: Data constructor for `NValue' t f m a` changed (`NValue -> NValue'`).
143145

144146
* Additional:
145147
* [(link)](https://github.com/haskell-nix/hnix/commit/7e6cd97bf3288cb584241611fdb25bf85d7e0ba7) `cabal.project`: freed from the `cryptohash-sha512` override, Hackage trustees made a revision.

src/Nix/Cited.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Lens.Family2.TH
1818

1919
import Nix.Expr.Types.Annotated
2020
import Nix.Scope
21-
import Nix.Value ( NValue, NValue'(NValue) )
21+
import Nix.Value ( NValue, NValue'(NValue') )
2222
import Control.Monad.Free ( Free(Pure, Free) )
2323

2424
data Provenance m v = Provenance
@@ -65,8 +65,8 @@ class HasCitations1 m v f where
6565

6666
instance HasCitations1 m v f
6767
=> HasCitations m v (NValue' t f m a) where
68-
citations (NValue f) = citations1 f
69-
addProvenance x (NValue f) = NValue (addProvenance1 x f)
68+
citations (NValue' f) = citations1 f
69+
addProvenance x (NValue' f) = NValue' (addProvenance1 x f)
7070

7171
instance (HasCitations1 m v f, HasCitations m v t)
7272
=> HasCitations m v (NValue t f m) where

src/Nix/Normal.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ stubCycles
107107
-> NValue t f m
108108
stubCycles = flip iterNValue Free $ \t _ ->
109109
Free
110-
$ NValue
110+
$ NValue'
111111
$ Prelude.foldr (addProvenance1 @m @(NValue t f m)) cyc
112112
$ reverse
113113
$ citations @m @(NValue t f m) t
114114
where
115-
Free (NValue cyc) = opaque
115+
Free (NValue' cyc) = opaque
116116

117117
removeEffects
118118
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)

src/Nix/Pretty.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ valueToExpr = iterNValue (\_ _ -> thk) phi
320320
phi (NVClosure' _ _ ) = Fix . NSym $ "<closure>"
321321
phi (NVPath' p ) = Fix $ NLiteralPath p
322322
phi (NVBuiltin' name _) = Fix . NSym $ "builtins." <> pack name
323-
phi _ = error "Pattern synonyms foil completeness check"
324323

325324
mkStr ns = Fix $ NStr $ DoubleQuoted [Plain (stringIgnoreContext ns)]
326325

@@ -396,4 +395,3 @@ printNix = iterNValue (\_ _ -> thk) phi
396395
phi NVClosure'{} = "<<lambda>>"
397396
phi (NVPath' fp ) = fp
398397
phi (NVBuiltin' name _) = "<<builtin " <> name <> ">>"
399-
phi _ = error "Pattern synonyms foil completeness check"

src/Nix/Standard.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ newtype StdCited m a = StdCited
8181
newtype StdThunk (m :: * -> *) = StdThunk
8282
{ _stdThunk :: StdCited m (NThunkF m (StdValue m)) }
8383

84+
type StdValue' m = NValue' (StdThunk m) (StdCited m) m (StdValue m)
8485
type StdValue m = NValue (StdThunk m) (StdCited m) m
8586

8687
instance Show (StdThunk m) where

src/Nix/Thunk/Basic.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ data NThunkF m v
3535
instance (Eq v, Eq (ThunkId m)) => Eq (NThunkF m v) where
3636
Thunk x _ _ == Thunk y _ _ = x == y
3737

38-
instance Show v => Show (NThunkF m v) where
38+
instance Show (NThunkF m v) where
3939
show Thunk{} = "<thunk>"
4040

4141
type MonadBasicThunk m = (MonadThunkId m, MonadVar m)

src/Nix/Value.hs

Lines changed: 91 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,72 @@ import Nix.Thunk
5555
import Nix.Utils
5656
import Data.Eq.Deriving
5757

58+
-- | An NValueF p m r represents all the possible types of Nix values.
59+
--
60+
-- Is is the base functor to form the Free monad of nix expressions.
61+
-- The parameter `r` represents Nix values in their final form (NValue).
62+
-- The parameter `p` represents exactly the same type, but is kept separate
63+
-- or it would prevent NValueF from being a proper functor.
64+
-- It is intended to be hard-coded to the same final type as r.
65+
-- `m` is the monad in which evaluations will run.
66+
67+
-- | An NValue' t f m a is a magic layer between NValueF and the Free monad construction.
68+
--
69+
-- It fixes the `p` parameter of NValueF to the final NValue type, making the
70+
-- definition of NValue' and NValue depend on each other in a recursive
71+
-- fashion.
72+
--
73+
-- It also introduces a `f` parameter for a custom functor that can be used
74+
-- to wrap each intermediate value in the reduced expression tree.
75+
-- This is where expression evaluations can store annotations and other
76+
-- useful information.
77+
--
78+
-- `t` is not really used here, but is needed to type the (NValue t f m)
79+
-- used to tie the knot of the `p` parameter in the inner NValueF.
80+
--
81+
-- `a` is will be an `NValue t f m` when NValue' functor is turned into a
82+
-- Free monad.
83+
84+
-- | 'NValue t f m' is the most reduced form of a 'NExpr' after evaluation is
85+
-- completed. It is a layer cake of NValueF base values, wrapped in the f
86+
-- functor and into the Free recursive construction.
87+
--
88+
-- Concretely, an NValue t f m can either be a thunk, representing a value
89+
-- yet to be evaluated (Pure t), or a know value in WHNF
90+
-- (Free (NValue' t f m (NValue t f m))) = (Free (f (NValueF NValue m NValue))
91+
-- That is, a base value type, wrapped into the generic `f`
92+
-- functor, and based on other NValue's, which can in turn be either thunks,
93+
-- or more already WHNF evaluated values.
94+
--
95+
-- As an example, the value `[1]` will be represented as
96+
--
97+
-- Free (f (NVListF [
98+
-- (Free (f (NVConstantF (NInt 1))))
99+
-- ]))
100+
--
101+
-- Should this 1 be a laziy and yet unevaluated value, it would be represented as
102+
--
103+
-- Free (f (NVListF [ (Pure t) ]))
104+
--
105+
-- Where the t is evaluator dependant, and should contain anough information
106+
-- to be evaluated to an NValue when needed. `demand` of `force` are used to
107+
-- turn a potential thunk into a `m (NValue t f m)`.
108+
--
109+
-- Of course, trees can be much bigger.
110+
--
111+
-- The number of layers and type aliases for similar things is huge, so
112+
-- this module provides ViewPatterns for each NValueF constructor.
113+
--
114+
-- For example, the pattern NVStr' ns matches a NValue' containing an NVStrF,
115+
-- and bind that NVStrF to ns, ignoring the f functor inside.
116+
-- Similarly, the pattern NVStr ns (without prime mark) will match the inner
117+
-- NVstrF value inside an NValue. Of course, the patterns are declined for
118+
-- all the NValueF constructors. The non primed version also has an NVThunk t
119+
-- pattern to account for the possibility of an NValue to no be fully
120+
-- evaluated yet, as opposed to an NValue'.
58121

59122
-- * @__NValueF__@: Base functor
60123

61-
-- | 'NValue' is the most reduced form of a 'NExpr' after evaluation is
62-
-- completed. 's' is related to the type of errors that might occur during
63-
-- construction or use of a value.
64124
data NValueF p m r
65125
= NVConstantF NAtom
66126
-- | A string has a value and a context, which can be used to record what a
@@ -219,15 +279,15 @@ hoistNValueF lft =
219279
-- | At the time of constructor, the expected arguments to closures are values
220280
-- that may contain thunks. The type of such thunks are fixed at that time.
221281
newtype NValue' t f m a =
222-
NValue
282+
NValue'
223283
{
224-
-- | Applying F-algebra carrier (@NValue@) to the F-algebra Base functor data type (@NValueF@), forming the \( F(A)-> A \)).
284+
-- | Applying F-algebra Base functor data type (@NValueF@) to the F-algebra carrier (@NValue@), forming the \( F(A)-> A \)).
225285
_nValue :: f (NValueF (NValue t f m) m a)
226286
}
227287
deriving (Generic, Typeable, Functor, Foldable)
228288

229289
instance (Comonad f, Show a) => Show (NValue' t f m a) where
230-
show (NValue (extract -> v)) = show v
290+
show (NValue' (extract -> v)) = show v
231291

232292

233293
-- ** Show1
@@ -242,7 +302,6 @@ instance Comonad f => Show1 (NValue' t f m) where
242302
NVPath' path -> showsUnaryWith showsPrec "NVPathF" p path
243303
NVClosure' c _ -> showsUnaryWith showsPrec "NVClosureF" p c
244304
NVBuiltin' name _ -> showsUnaryWith showsPrec "NVBuiltinF" p name
245-
_ -> error "Pattern synonyms mask coverage"
246305

247306

248307
-- ** Traversable
@@ -253,8 +312,8 @@ sequenceNValue'
253312
=> (forall x . n x -> m x)
254313
-> NValue' t f m (n a)
255314
-> n (NValue' t f m a)
256-
sequenceNValue' transform (NValue v) =
257-
NValue <$> traverse (sequenceNValueF transform) v
315+
sequenceNValue' transform (NValue' v) =
316+
NValue' <$> traverse (sequenceNValueF transform) v
258317

259318

260319
-- ** Profunctor
@@ -292,8 +351,8 @@ hoistNValue'
292351
-> (forall x . m x -> n x)
293352
-> NValue' t f m a
294353
-> NValue' t f n a
295-
hoistNValue' run lft (NValue v) =
296-
NValue $ lmapNValueF (hoistNValue lft run) . hoistNValueF lft <$> v
354+
hoistNValue' run lft (NValue' v) =
355+
NValue' $ lmapNValueF (hoistNValue lft run) . hoistNValueF lft <$> v
297356
{-# inline hoistNValue' #-}
298357

299358
-- ** Monad
@@ -305,8 +364,8 @@ bindNValue'
305364
-> (a -> n b)
306365
-> NValue' t f m a
307366
-> n (NValue' t f m b)
308-
bindNValue' transform f (NValue v) =
309-
NValue <$> traverse (bindNValueF transform f) v
367+
bindNValue' transform f (NValue' v) =
368+
NValue' <$> traverse (bindNValueF transform f) v
310369

311370
-- *** MonadTrans
312371

@@ -355,36 +414,36 @@ unliftNValue' = hoistNValue' lift
355414
nvConstant' :: Applicative f
356415
=> NAtom
357416
-> NValue' t f m r
358-
nvConstant' = NValue . pure . NVConstantF
417+
nvConstant' = NValue' . pure . NVConstantF
359418

360419

361420
-- | Haskell text & context to the Nix text & context,
362421
nvStr' :: Applicative f
363422
=> NixString
364423
-> NValue' t f m r
365-
nvStr' = NValue . pure . NVStrF
424+
nvStr' = NValue' . pure . NVStrF
366425

367426

368427
-- | Haskell @FilePath@ to the Nix path,
369428
nvPath' :: Applicative f
370429
=> FilePath
371430
-> NValue' t f m r
372-
nvPath' = NValue . pure . NVPathF
431+
nvPath' = NValue' . pure . NVPathF
373432

374433

375434
-- | Haskell @[]@ to the Nix @[]@,
376435
nvList' :: Applicative f
377436
=> [r]
378437
-> NValue' t f m r
379-
nvList' = NValue . pure . NVListF
438+
nvList' = NValue' . pure . NVListF
380439

381440

382441
-- | Haskell key-value to the Nix key-value,
383442
nvSet' :: Applicative f
384443
=> HashMap Text SourcePos
385444
-> HashMap Text r
386445
-> NValue' t f m r
387-
nvSet' x s = NValue $ pure $ NVSetF s x
446+
nvSet' x s = NValue' $ pure $ NVSetF s x
388447

389448

390449
-- | Haskell closure to the Nix closure,
@@ -394,15 +453,15 @@ nvClosure' :: (Applicative f, Functor m)
394453
-> m r
395454
)
396455
-> NValue' t f m r
397-
nvClosure' x f = NValue $ pure $ NVClosureF x f
456+
nvClosure' x f = NValue' $ pure $ NVClosureF x f
398457

399458

400459
-- | Haskell functions to the Nix functions!
401460
nvBuiltin' :: (Applicative f, Functor m)
402461
=> String
403462
-> (NValue t f m -> m r)
404463
-> NValue' t f m r
405-
nvBuiltin' name f = NValue $ pure $ NVBuiltinF name f
464+
nvBuiltin' name f = NValue' $ pure $ NVBuiltinF name f
406465

407466

408467
-- So above we have maps of Hask subcategory objects to Nix objects,
@@ -417,13 +476,14 @@ nvBuiltin' name f = NValue $ pure $ NVBuiltinF name f
417476
-- the @NValueF a@. Which is @NValueF p m r@. Since it extracted from the
418477
-- @NValue@, which is formed by \( (F a -> a) F a \) in the first place.
419478
-- So @NValueF p m r@ which is extracted here, internally holds the next NValue.
420-
pattern NVConstant' x <- NValue (extract -> NVConstantF x)
421-
pattern NVStr' ns <- NValue (extract -> NVStrF ns)
422-
pattern NVPath' x <- NValue (extract -> NVPathF x)
423-
pattern NVList' l <- NValue (extract -> NVListF l)
424-
pattern NVSet' s x <- NValue (extract -> NVSetF s x)
425-
pattern NVClosure' x f <- NValue (extract -> NVClosureF x f)
426-
pattern NVBuiltin' name f <- NValue (extract -> NVBuiltinF name f)
479+
pattern NVConstant' x <- NValue' (extract -> NVConstantF x)
480+
pattern NVStr' ns <- NValue' (extract -> NVStrF ns)
481+
pattern NVPath' x <- NValue' (extract -> NVPathF x)
482+
pattern NVList' l <- NValue' (extract -> NVListF l)
483+
pattern NVSet' s x <- NValue' (extract -> NVSetF s x)
484+
pattern NVClosure' x f <- NValue' (extract -> NVClosureF x f)
485+
pattern NVBuiltin' name f <- NValue' (extract -> NVBuiltinF name f)
486+
{-# COMPLETE NVConstant', NVStr', NVPath', NVList', NVSet', NVClosure', NVBuiltin' #-}
427487

428488

429489
-- * @__NValue__@: Nix language values
@@ -609,13 +669,16 @@ builtin3 name f =
609669
-- *** @F: Evaluation -> NValue@
610670

611671
pattern NVThunk t <- Pure t
672+
pattern NVValue v <- Free v
673+
{-# COMPLETE NVThunk, NVValue #-}
612674
pattern NVConstant x <- Free (NVConstant' x)
613675
pattern NVStr ns <- Free (NVStr' ns)
614676
pattern NVPath x <- Free (NVPath' x)
615677
pattern NVList l <- Free (NVList' l)
616678
pattern NVSet s x <- Free (NVSet' s x)
617679
pattern NVClosure x f <- Free (NVClosure' x f)
618680
pattern NVBuiltin name f <- Free (NVBuiltin' name f)
681+
{-# COMPLETE NVThunk, NVConstant, NVStr, NVPath, NVList, NVSet, NVClosure, NVBuiltin #-}
619682

620683

621684

@@ -685,7 +748,7 @@ showValueType :: (MonadThunk t m (NValue t f m), Comonad f)
685748
=> NValue t f m
686749
-> m String
687750
showValueType (Pure t) = showValueType =<< force t
688-
showValueType (Free (NValue (extract -> v))) =
751+
showValueType (Free (NValue' (extract -> v))) =
689752
pure $ describeValue $ valueType v
690753

691754

src/Nix/Value/Equal.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ valueEqM
189189
valueEqM ( Pure x) ( Pure y) = thunkEqM x y
190190
valueEqM ( Pure x) y@(Free _) = thunkEqM x =<< thunk (pure y)
191191
valueEqM x@(Free _) ( Pure y) = (`thunkEqM` y) =<< thunk (pure x)
192-
valueEqM (Free (NValue (extract -> x))) (Free (NValue (extract -> y))) =
192+
valueEqM (Free (NValue' (extract -> x))) (Free (NValue' (extract -> y))) =
193193
valueFEqM
194194
(compareAttrSetsM f valueEqM)
195195
valueEqM

src/Nix/XML.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ toXML = runWithStringContext . fmap pp . iterNValue (\_ _ -> cyc) phi
6161
pure $ Element (unqual "function") mempty (paramsXML p) Nothing
6262
NVPath' fp -> pure $ mkElem "path" "value" fp
6363
NVBuiltin' name _ -> pure $ mkElem "function" "name" name
64-
_ -> error "Pattern synonyms mask coverage"
6564

6665
mkElem :: String -> String -> String -> Element
6766
mkElem n a v = Element (unqual n) [Attr (unqual a) v] mempty Nothing

0 commit comments

Comments
 (0)