@@ -55,12 +55,72 @@ import Nix.Thunk
5555import Nix.Utils
5656import 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.
64124data 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.
221281newtype 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
229289instance (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
355414nvConstant' :: 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,
362421nvStr' :: 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,
369428nvPath' :: 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 @[]@,
376435nvList' :: 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,
383442nvSet' :: 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!
401460nvBuiltin' :: (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
611671pattern NVThunk t <- Pure t
672+ pattern NVValue v <- Free v
673+ {-# COMPLETE NVThunk, NVValue #-}
612674pattern NVConstant x <- Free (NVConstant' x)
613675pattern NVStr ns <- Free (NVStr' ns)
614676pattern NVPath x <- Free (NVPath' x)
615677pattern NVList l <- Free (NVList' l)
616678pattern NVSet s x <- Free (NVSet' s x)
617679pattern NVClosure x f <- Free (NVClosure' x f)
618680pattern 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
687750showValueType (Pure t) = showValueType =<< force t
688- showValueType (Free (NValue (extract -> v))) =
751+ showValueType (Free (NValue' (extract -> v))) =
689752 pure $ describeValue $ valueType v
690753
691754
0 commit comments