Begin work on harmonizing the two different value representations
This commit is contained in:
parent
f5d070af16
commit
522585a7f1
|
@ -41,15 +41,3 @@ points in the code are generic over both.
|
||||||
Having said that, I should mention that there are two different types of
|
Having said that, I should mention that there are two different types of
|
||||||
values: `NValue` and `NValueNF`. The former is created by evaluating an
|
values: `NValue` and `NValueNF`. The former is created by evaluating an
|
||||||
`NExpr`, and then latter by calling `normalForm` on an `NValue`.
|
`NExpr`, and then latter by calling `normalForm` on an `NValue`.
|
||||||
|
|
||||||
However, not every term can be reduced to normal form. There are cases where
|
|
||||||
Nix allows a cycle to exist in the data, so that it can printed simply as
|
|
||||||
`<CYCLE>`. To represent this, we use a simple recursive type for `NValue`, but
|
|
||||||
a `Free` construction for `NValueNF`:
|
|
||||||
|
|
||||||
type NValueNF t f m = Free (NValue' t f m) t
|
|
||||||
|
|
||||||
The idea here is that `Free` values are those we were able to normalize (since
|
|
||||||
it has its own terminating base cases of constants, strings, etc), while the
|
|
||||||
`Pure` thunk is the thunk we'd seen before while normalizing, indicating the
|
|
||||||
beginning of the cycle.
|
|
||||||
|
|
|
@ -475,6 +475,7 @@ library
|
||||||
Nix.Utils
|
Nix.Utils
|
||||||
Nix.Value
|
Nix.Value
|
||||||
Nix.Value.Equal
|
Nix.Value.Equal
|
||||||
|
Nix.Value.Monad
|
||||||
Nix.Var
|
Nix.Var
|
||||||
Nix.XML
|
Nix.XML
|
||||||
other-modules:
|
other-modules:
|
||||||
|
|
|
@ -126,7 +126,8 @@ withNixContext mpath action = do
|
||||||
let ref = wrapValue @t @m @(NValue t f m) $ nvPath path
|
let ref = wrapValue @t @m @(NValue t f m) $ nvPath path
|
||||||
pushScope (M.singleton "__cur_file" ref) action
|
pushScope (M.singleton "__cur_file" ref) action
|
||||||
|
|
||||||
builtins :: (MonadNix e t f m, Scoped t m) => m (Scopes m t)
|
builtins :: (MonadNix e t f m, Scoped (NValue t f m) m)
|
||||||
|
=> m (Scopes m (NValue t f m))
|
||||||
builtins = do
|
builtins = do
|
||||||
ref <- thunk $ flip nvSet M.empty <$> buildMap
|
ref <- thunk $ flip nvSet M.empty <$> buildMap
|
||||||
lst <- ([("builtins", ref)] ++) <$> topLevelBuiltins
|
lst <- ([("builtins", ref)] ++) <$> topLevelBuiltins
|
||||||
|
|
|
@ -21,8 +21,8 @@ import Lens.Family2.TH
|
||||||
import Nix.Expr.Types.Annotated
|
import Nix.Expr.Types.Annotated
|
||||||
import Nix.Scope
|
import Nix.Scope
|
||||||
|
|
||||||
data Provenance t m v = Provenance
|
data Provenance m v = Provenance
|
||||||
{ _lexicalScope :: Scopes m t
|
{ _lexicalScope :: Scopes m v
|
||||||
, _originExpr :: NExprLocF (Maybe v)
|
, _originExpr :: NExprLocF (Maybe v)
|
||||||
-- ^ When calling the function x: x + 2 with argument x = 3, the
|
-- ^ When calling the function x: x + 2 with argument x = 3, the
|
||||||
-- 'originExpr' for the resulting value will be 3 + 2, while the
|
-- 'originExpr' for the resulting value will be 3 + 2, while the
|
||||||
|
@ -31,34 +31,34 @@ data Provenance t m v = Provenance
|
||||||
}
|
}
|
||||||
deriving (Generic, Typeable, Show)
|
deriving (Generic, Typeable, Show)
|
||||||
|
|
||||||
data NCited t m v a = NCited
|
data NCited m v a = NCited
|
||||||
{ _provenance :: [Provenance t m v]
|
{ _provenance :: [Provenance m v]
|
||||||
, _cited :: a
|
, _cited :: a
|
||||||
}
|
}
|
||||||
deriving (Generic, Typeable, Functor, Foldable, Traversable, Show)
|
deriving (Generic, Typeable, Functor, Foldable, Traversable, Show)
|
||||||
|
|
||||||
instance Applicative (NCited t m v) where
|
instance Applicative (NCited m v) where
|
||||||
pure = NCited []
|
pure = NCited []
|
||||||
NCited xs f <*> NCited ys x = NCited (xs <> ys) (f x)
|
NCited xs f <*> NCited ys x = NCited (xs <> ys) (f x)
|
||||||
|
|
||||||
instance Comonad (NCited t m v) where
|
instance Comonad (NCited m v) where
|
||||||
duplicate p = NCited (_provenance p) p
|
duplicate p = NCited (_provenance p) p
|
||||||
extract = _cited
|
extract = _cited
|
||||||
|
|
||||||
instance ComonadEnv [Provenance t m v] (NCited t m v) where
|
instance ComonadEnv [Provenance m v] (NCited m v) where
|
||||||
ask = _provenance
|
ask = _provenance
|
||||||
|
|
||||||
$(makeLenses ''Provenance)
|
$(makeLenses ''Provenance)
|
||||||
$(makeLenses ''NCited)
|
$(makeLenses ''NCited)
|
||||||
|
|
||||||
class HasCitations t m v a where
|
class HasCitations m v a where
|
||||||
citations :: a -> [Provenance t m v]
|
citations :: a -> [Provenance m v]
|
||||||
addProvenance :: Provenance t m v -> a -> a
|
addProvenance :: Provenance m v -> a -> a
|
||||||
|
|
||||||
instance HasCitations t m v (NCited t m v a) where
|
instance HasCitations m v (NCited m v a) where
|
||||||
citations = _provenance
|
citations = _provenance
|
||||||
addProvenance x (NCited p v) = (NCited (x : p) v)
|
addProvenance x (NCited p v) = (NCited (x : p) v)
|
||||||
|
|
||||||
class HasCitations1 t m v f where
|
class HasCitations1 m v f where
|
||||||
citations1 :: f a -> [Provenance t m v]
|
citations1 :: f a -> [Provenance m v]
|
||||||
addProvenance1 :: Provenance t m v -> f a -> f a
|
addProvenance1 :: Provenance m v -> f a -> f a
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE MultiWayIf #-}
|
{-# LANGUAGE MultiWayIf #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE QuantifiedConstraints #-}
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
{-# LANGUAGE TupleSections #-}
|
{-# LANGUAGE TupleSections #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
|
@ -27,10 +28,9 @@
|
||||||
|
|
||||||
module Nix.Convert where
|
module Nix.Convert where
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad.Free
|
||||||
import Control.Monad.Catch
|
|
||||||
import Data.ByteString
|
import Data.ByteString
|
||||||
import Data.HashMap.Lazy ( HashMap )
|
import Data.Fix
|
||||||
import qualified Data.HashMap.Lazy as M
|
import qualified Data.HashMap.Lazy as M
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
|
@ -44,8 +44,9 @@ import Nix.Expr.Types
|
||||||
import Nix.Expr.Types.Annotated
|
import Nix.Expr.Types.Annotated
|
||||||
import Nix.Frames
|
import Nix.Frames
|
||||||
import Nix.String
|
import Nix.String
|
||||||
import Nix.Thunk
|
|
||||||
import Nix.Value
|
import Nix.Value
|
||||||
|
import Nix.Value.Monad
|
||||||
|
import Nix.Utils
|
||||||
|
|
||||||
{-
|
{-
|
||||||
|
|
||||||
|
@ -60,144 +61,104 @@ Do not add these instances back!
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
{-----------------------------------------------------------------------
|
||||||
|
FromValue
|
||||||
|
-----------------------------------------------------------------------}
|
||||||
|
|
||||||
class FromValue a m v where
|
class FromValue a m v where
|
||||||
fromValue :: v -> m a
|
fromValue :: v -> m a
|
||||||
fromValueMay :: v -> m (Maybe a)
|
fromValueMay :: v -> m (Maybe a)
|
||||||
|
|
||||||
type Convertible e t f m
|
type Convertible e t f m = (Framed e m, MonadDataErrorContext t f m)
|
||||||
= (Framed e m, MonadThunk t m (NValue t f m), MonadDataErrorContext t f m)
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue () m (NValueNF t f m) where
|
instance (Monad m, FromValue a m v) => FromValue a m (m v) where
|
||||||
fromValueMay = \case
|
fromValueMay = (>>= fromValueMay)
|
||||||
NVConstantNF NNull -> pure $ Just ()
|
fromValue = (>>= fromValue)
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TNull v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue () m (NValue t f m) where
|
instance ( Convertible e t f m
|
||||||
|
, MonadValue (NValueNF t f m) m
|
||||||
|
, FromValue a m (NValue' t f m (NValueNF t f m))
|
||||||
|
)
|
||||||
|
=> FromValue a m (NValueNF t f m) where
|
||||||
|
fromValueMay = flip demand $ \(Fix v) -> fromValueMay v
|
||||||
|
fromValue = flip demand $ \(Fix v) -> fromValue v
|
||||||
|
|
||||||
|
instance ( Convertible e t f m
|
||||||
|
, MonadValue (NValue t f m) m
|
||||||
|
, FromValue a m (NValue' t f m (NValue t f m))
|
||||||
|
)
|
||||||
|
=> FromValue a m (NValue t f m) where
|
||||||
|
fromValueMay = flip demand $ \case
|
||||||
|
Pure _ -> pure Nothing
|
||||||
|
Free v -> fromValueMay v
|
||||||
|
fromValue = flip demand $ \case
|
||||||
|
Pure t -> throwError $ ForcingThunk @t @f @m t
|
||||||
|
Free v -> fromValue v
|
||||||
|
|
||||||
|
instance (Convertible e t f m, Show r) => FromValue () m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVConstant NNull -> pure $ Just ()
|
NVConstant' NNull -> pure $ Just ()
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TNull v
|
_ -> throwError $ Expectation TNull v
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Bool m (NValueNF t f m) where
|
instance (Convertible e t f m, Show r) => FromValue Bool m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVConstantNF (NBool b) -> pure $ Just b
|
NVConstant' (NBool b) -> pure $ Just b
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TBool v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Bool m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVConstant (NBool b) -> pure $ Just b
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TBool v
|
_ -> throwError $ Expectation TBool v
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Int m (NValueNF t f m) where
|
instance (Convertible e t f m, Show r) => FromValue Int m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVConstantNF (NInt b) -> pure $ Just (fromInteger b)
|
NVConstant' (NInt b) -> pure $ Just (fromInteger b)
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TInt v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Int m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVConstant (NInt b) -> pure $ Just (fromInteger b)
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TInt v
|
_ -> throwError $ Expectation TInt v
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Integer m (NValueNF t f m) where
|
instance (Convertible e t f m, Show r) => FromValue Integer m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVConstantNF (NInt b) -> pure $ Just b
|
NVConstant' (NInt b) -> pure $ Just b
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TInt v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Integer m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVConstant (NInt b) -> pure $ Just b
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TInt v
|
_ -> throwError $ Expectation TInt v
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Float m (NValueNF t f m) where
|
instance (Convertible e t f m, Show r) => FromValue Float m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVConstantNF (NFloat b) -> pure $ Just b
|
NVConstant' (NFloat b) -> pure $ Just b
|
||||||
NVConstantNF (NInt i) -> pure $ Just (fromInteger i)
|
NVConstant' (NInt i) -> pure $ Just (fromInteger i)
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TFloat v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Float m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVConstant (NFloat b) -> pure $ Just b
|
|
||||||
NVConstant (NInt i) -> pure $ Just (fromInteger i)
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TFloat v
|
_ -> throwError $ Expectation TFloat v
|
||||||
|
|
||||||
instance (Convertible e t f m, MonadEffects t f m)
|
instance (Convertible e t f m, Show r, MonadEffects t f m,
|
||||||
=> FromValue NixString m (NValueNF t f m) where
|
FromValue NixString m r)
|
||||||
|
=> FromValue NixString m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVStrNF ns -> pure $ Just ns
|
NVStr' ns -> pure $ Just ns
|
||||||
NVPathNF p ->
|
NVPath' p ->
|
||||||
Just
|
Just
|
||||||
. hackyMakeNixStringWithoutContext
|
. hackyMakeNixStringWithoutContext
|
||||||
. Text.pack
|
. Text.pack
|
||||||
. unStorePath
|
. unStorePath
|
||||||
<$> addPath p
|
<$> addPath p
|
||||||
NVSetNF s _ -> case M.lookup "outPath" s of
|
NVSet' s _ -> case M.lookup "outPath" s of
|
||||||
Nothing -> pure Nothing
|
Nothing -> pure Nothing
|
||||||
Just p -> fromValueMay p
|
Just p -> fromValueMay p
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF (TString NoContext) v
|
|
||||||
|
|
||||||
instance (Convertible e t f m, MonadEffects t f m)
|
|
||||||
=> FromValue NixString m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVStr ns -> pure $ Just ns
|
|
||||||
NVPath p ->
|
|
||||||
Just
|
|
||||||
. hackyMakeNixStringWithoutContext
|
|
||||||
. Text.pack
|
|
||||||
. unStorePath
|
|
||||||
<$> addPath p
|
|
||||||
NVSet s _ -> case M.lookup "outPath" s of
|
|
||||||
Nothing -> pure Nothing
|
|
||||||
Just p -> force p fromValueMay
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation (TString NoContext) v
|
_ -> throwError $ Expectation (TString NoContext) v
|
||||||
|
|
||||||
instance Convertible e t f m
|
instance (Convertible e t f m, Show r)
|
||||||
=> FromValue ByteString m (NValueNF t f m) where
|
=> FromValue ByteString m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVStrNF ns -> pure $ encodeUtf8 <$> hackyGetStringNoContext ns
|
NVStr' ns -> pure $ encodeUtf8 <$> hackyGetStringNoContext ns
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF (TString NoContext) v
|
|
||||||
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> FromValue ByteString m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVStr ns -> pure $ encodeUtf8 <$> hackyGetStringNoContext ns
|
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
|
@ -206,191 +167,125 @@ instance Convertible e t f m
|
||||||
newtype Path = Path { getPath :: FilePath }
|
newtype Path = Path { getPath :: FilePath }
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Path m (NValueNF t f m) where
|
instance (Convertible e t f m, Show r, FromValue Path m r)
|
||||||
|
=> FromValue Path m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVPathNF p -> pure $ Just (Path p)
|
NVPath' p -> pure $ Just (Path p)
|
||||||
NVStrNF ns -> pure $ Path . Text.unpack <$> hackyGetStringNoContext ns
|
NVStr' ns -> pure $ Path . Text.unpack <$> hackyGetStringNoContext ns
|
||||||
NVSetNF s _ -> case M.lookup "outPath" s of
|
NVSet' s _ -> case M.lookup "outPath" s of
|
||||||
Nothing -> pure Nothing
|
Nothing -> pure Nothing
|
||||||
Just p -> fromValueMay @Path p
|
Just p -> fromValueMay @Path p
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TPath v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue Path m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVPath p -> pure $ Just (Path p)
|
|
||||||
NVStr ns -> pure $ Path . Text.unpack <$> hackyGetStringNoContext ns
|
|
||||||
NVSet s _ -> case M.lookup "outPath" s of
|
|
||||||
Nothing -> pure Nothing
|
|
||||||
Just p -> force p $ fromValueMay @Path
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TPath v
|
_ -> throwError $ Expectation TPath v
|
||||||
|
|
||||||
instance (Convertible e t f m, FromValue a m (NValueNF t f m), Show a)
|
instance (Convertible e t f m, Show r)
|
||||||
=> FromValue [a] m (NValueNF t f m) where
|
=> FromValue [r] m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVListNF l -> sequence <$> traverse fromValueMay l
|
NVList' l -> pure $ Just l
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TList v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromValue [t] m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVList l -> pure $ Just l
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TList v
|
_ -> throwError $ Expectation TList v
|
||||||
|
|
||||||
instance Convertible e t f m
|
instance (Convertible e t f m, Show r)
|
||||||
=> FromValue (HashMap Text (NValueNF t f m)) m (NValueNF t f m) where
|
=> FromValue (AttrSet r) m (NValue' t f m r) where
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVSetNF s _ -> pure $ Just s
|
NVSet' s _ -> pure $ Just s
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TSet v
|
|
||||||
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> FromValue (HashMap Text t) m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVSet s _ -> pure $ Just s
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TSet v
|
_ -> throwError $ Expectation TSet v
|
||||||
|
|
||||||
instance Convertible e t f m
|
instance (Convertible e t f m, Show r)
|
||||||
=> FromValue (HashMap Text (NValueNF t f m),
|
=> FromValue (AttrSet r, AttrSet SourcePos) m (NValue' t f m r) where
|
||||||
HashMap Text SourcePos) m (NValueNF t f m) where
|
|
||||||
fromValueMay = \case
|
fromValueMay = \case
|
||||||
NVSetNF s p -> pure $ Just (s, p)
|
NVSet' s p -> pure $ Just (s, p)
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
fromValue v = fromValueMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ ExpectationNF TSet v
|
|
||||||
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> FromValue (HashMap Text t,
|
|
||||||
HashMap Text SourcePos) m (NValue t f m) where
|
|
||||||
fromValueMay = \case
|
|
||||||
NVSet s p -> pure $ Just (s, p)
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromValue v = fromValueMay v >>= \case
|
fromValue v = fromValueMay v >>= \case
|
||||||
Just b -> pure b
|
Just b -> pure b
|
||||||
_ -> throwError $ Expectation TSet v
|
_ -> throwError $ Expectation TSet v
|
||||||
|
|
||||||
instance (Monad m, FromValue a m v) => FromValue a m (m v) where
|
{-----------------------------------------------------------------------
|
||||||
fromValueMay = (>>= fromValueMay)
|
ToValue
|
||||||
fromValue = (>>= fromValue)
|
-----------------------------------------------------------------------}
|
||||||
|
|
||||||
class ToValue a m v where
|
class ToValue a m v where
|
||||||
toValue :: a -> m v
|
toValue :: a -> m v
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue () m (NValueNF t f m) where
|
instance (Monad m, ToValue a m v) => ToValue a m (m v) where
|
||||||
toValue _ = pure . nvConstantNF $ NNull
|
toValue = pure . toValue
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue () m (NValue t f m) where
|
instance (Convertible e t f m, forall r. Show r => ToValue a m (NValue' t f m r))
|
||||||
toValue _ = pure . nvConstant $ NNull
|
=> ToValue a m (NValueNF t f m) where
|
||||||
|
toValue = fmap Fix . toValue
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Bool m (NValueNF t f m) where
|
instance (Convertible e t f m, forall r. Show r => ToValue a m (NValue' t f m r))
|
||||||
toValue = pure . nvConstantNF . NBool
|
=> ToValue a m (NValue t f m) where
|
||||||
|
toValue = fmap Free . toValue
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Bool m (NValue t f m) where
|
instance Convertible e t f m => ToValue () m (NValue' t f m r) where
|
||||||
toValue = pure . nvConstant . NBool
|
toValue _ = pure . nvConstant' $ NNull
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Int m (NValueNF t f m) where
|
instance Convertible e t f m => ToValue Bool m (NValue' t f m r) where
|
||||||
toValue = pure . nvConstantNF . NInt . toInteger
|
toValue = pure . nvConstant' . NBool
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Int m (NValue t f m) where
|
instance Convertible e t f m => ToValue Int m (NValue' t f m r) where
|
||||||
toValue = pure . nvConstant . NInt . toInteger
|
toValue = pure . nvConstant' . NInt . toInteger
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Integer m (NValueNF t f m) where
|
instance Convertible e t f m => ToValue Integer m (NValue' t f m r) where
|
||||||
toValue = pure . nvConstantNF . NInt
|
toValue = pure . nvConstant' . NInt
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Integer m (NValue t f m) where
|
instance Convertible e t f m => ToValue Float m (NValue' t f m r) where
|
||||||
toValue = pure . nvConstant . NInt
|
toValue = pure . nvConstant' . NFloat
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Float m (NValueNF t f m) where
|
instance Convertible e t f m => ToValue NixString m (NValue' t f m r) where
|
||||||
toValue = pure . nvConstantNF . NFloat
|
toValue = pure . nvStr'
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Float m (NValue t f m) where
|
instance Convertible e t f m => ToValue ByteString m (NValue' t f m r) where
|
||||||
toValue = pure . nvConstant . NFloat
|
toValue = pure . nvStr' . hackyMakeNixStringWithoutContext . decodeUtf8
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue NixString m (NValueNF t f m) where
|
instance Convertible e t f m => ToValue Path m (NValue' t f m r) where
|
||||||
toValue = pure . nvStrNF
|
toValue = pure . nvPath' . getPath
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue NixString m (NValue t f m) where
|
instance Convertible e t f m => ToValue StorePath m (NValue' t f m r) where
|
||||||
toValue = pure . nvStr
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue ByteString m (NValueNF t f m) where
|
|
||||||
toValue = pure . nvStrNF . hackyMakeNixStringWithoutContext . decodeUtf8
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue ByteString m (NValue t f m) where
|
|
||||||
toValue = pure . nvStr . hackyMakeNixStringWithoutContext . decodeUtf8
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Path m (NValueNF t f m) where
|
|
||||||
toValue = pure . nvPathNF . getPath
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Path m (NValue t f m) where
|
|
||||||
toValue = pure . nvPath . getPath
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue StorePath m (NValueNF t f m) where
|
|
||||||
toValue = toValue . Path . unStorePath
|
toValue = toValue . Path . unStorePath
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue StorePath m (NValue t f m) where
|
instance ( Convertible e t f m
|
||||||
toValue = toValue . Path . unStorePath
|
, ToValue NixString m r
|
||||||
|
, ToValue Int m r
|
||||||
instance Convertible e t f m => ToValue SourcePos m (NValue t f m) where
|
)
|
||||||
|
=> ToValue SourcePos m (NValue' t f m r) where
|
||||||
toValue (SourcePos f l c) = do
|
toValue (SourcePos f l c) = do
|
||||||
f' <- pure $ nvStr $ principledMakeNixStringWithoutContext (Text.pack f)
|
f' <- toValue (principledMakeNixStringWithoutContext (Text.pack f))
|
||||||
l' <- toValue (unPos l)
|
l' <- toValue (unPos l)
|
||||||
c' <- toValue (unPos c)
|
c' <- toValue (unPos c)
|
||||||
let pos = M.fromList
|
let pos = M.fromList
|
||||||
[ ("file" :: Text, wrapValue f')
|
[ ("file" :: Text, f')
|
||||||
, ("line" , wrapValue l')
|
, ("line" , l')
|
||||||
, ("column" , wrapValue c')
|
, ("column" , c')
|
||||||
]
|
]
|
||||||
pure $ nvSet pos mempty
|
pure $ nvSet' pos mempty
|
||||||
|
|
||||||
instance (Convertible e t f m, ToValue a m (NValueNF t f m))
|
instance Convertible e t f m => ToValue [r] m (NValue' t f m r) where
|
||||||
=> ToValue [a] m (NValueNF t f m) where
|
toValue = pure . nvList'
|
||||||
toValue = fmap nvListNF . traverse toValue
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue [t] m (NValue t f m) where
|
instance Convertible e t f m => ToValue (AttrSet r) m (NValue' t f m r) where
|
||||||
toValue = pure . nvList
|
toValue = pure . flip nvSet' M.empty
|
||||||
|
|
||||||
instance Convertible e t f m
|
instance Convertible e t f m
|
||||||
=> ToValue (HashMap Text (NValueNF t f m)) m (NValueNF t f m) where
|
=> ToValue (AttrSet r, AttrSet SourcePos) m (NValue' t f m r) where
|
||||||
toValue = pure . flip nvSetNF M.empty
|
toValue (s, p) = pure $ nvSet' s p
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue (HashMap Text t) m (NValue t f m) where
|
instance ( MonadValue (NValue t f m) m
|
||||||
toValue = pure . flip nvSet M.empty
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue (HashMap Text (NValueNF t f m),
|
|
||||||
HashMap Text SourcePos) m (NValueNF t f m) where
|
|
||||||
toValue (s, p) = pure $ nvSetNF s p
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue (HashMap Text t,
|
|
||||||
HashMap Text SourcePos) m (NValue t f m) where
|
|
||||||
toValue (s, p) = pure $ nvSet s p
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue Bool m (NExprF r) where
|
|
||||||
toValue = pure . NConstant . NBool
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToValue () m (NExprF r) where
|
|
||||||
toValue _ = pure . NConstant $ NNull
|
|
||||||
|
|
||||||
instance ( MonadThunk t m (NValue t f m)
|
|
||||||
, MonadDataErrorContext t f m
|
, MonadDataErrorContext t f m
|
||||||
, Framed e m
|
, Framed e m
|
||||||
|
, ToValue NixString m r
|
||||||
|
, ToValue Bool m r
|
||||||
|
, ToValue [r] m r
|
||||||
)
|
)
|
||||||
=> ToValue NixLikeContextValue m (NValue t f m) where
|
=> ToValue NixLikeContextValue m (NValue' t f m r) where
|
||||||
toValue nlcv = do
|
toValue nlcv = do
|
||||||
path <- if nlcvPath nlcv then Just <$> toValue True else return Nothing
|
path <- if nlcvPath nlcv then Just <$> toValue True else return Nothing
|
||||||
allOutputs <- if nlcvAllOutputs nlcv
|
allOutputs <- if nlcvAllOutputs nlcv
|
||||||
|
@ -399,130 +294,18 @@ instance ( MonadThunk t m (NValue t f m)
|
||||||
outputs <- do
|
outputs <- do
|
||||||
let outputs =
|
let outputs =
|
||||||
fmap principledMakeNixStringWithoutContext $ nlcvOutputs nlcv
|
fmap principledMakeNixStringWithoutContext $ nlcvOutputs nlcv
|
||||||
outputsM :: [NValue t f m] <- traverse toValue outputs
|
ts :: [r] <- traverse toValue outputs
|
||||||
let ts :: [t] = fmap wrapValue outputsM
|
|
||||||
case ts of
|
case ts of
|
||||||
[] -> return Nothing
|
[] -> return Nothing
|
||||||
_ -> Just <$> toValue ts
|
_ -> Just <$> toValue ts
|
||||||
pure $ flip nvSet M.empty $ M.fromList $ catMaybes
|
pure $ flip nvSet' M.empty $ M.fromList $ catMaybes
|
||||||
[ (\p -> ("path", wrapValue p)) <$> path
|
[ (\p -> ("path", p)) <$> path
|
||||||
, (\ao -> ("allOutputs", wrapValue ao)) <$> allOutputs
|
, (\ao -> ("allOutputs", ao)) <$> allOutputs
|
||||||
, (\os -> ("outputs", wrapValue os)) <$> outputs
|
, (\os -> ("outputs", os)) <$> outputs
|
||||||
]
|
]
|
||||||
|
|
||||||
whileForcingThunk
|
instance Convertible e t f m => ToValue () m (NExprF r) where
|
||||||
:: forall t f m s e r . (Exception s, Convertible e t f m) => s -> m r -> m r
|
toValue _ = pure . NConstant $ NNull
|
||||||
whileForcingThunk frame =
|
|
||||||
withFrame Debug (ForcingThunk @t @f @m) . withFrame Debug frame
|
|
||||||
|
|
||||||
class FromNix a m v where
|
instance Convertible e t f m => ToValue Bool m (NExprF r) where
|
||||||
fromNix :: v -> m a
|
toValue = pure . NConstant . NBool
|
||||||
default fromNix :: FromValue a m v => v -> m a
|
|
||||||
fromNix = fromValue
|
|
||||||
|
|
||||||
fromNixMay :: v -> m (Maybe a)
|
|
||||||
default fromNixMay :: FromValue a m v => v -> m (Maybe a)
|
|
||||||
fromNixMay = fromValueMay
|
|
||||||
|
|
||||||
instance (Convertible e t f m, FromNix a m (NValue t f m))
|
|
||||||
=> FromNix [a] m (NValue t f m) where
|
|
||||||
fromNixMay = \case
|
|
||||||
NVList l -> sequence <$> traverse (`force` fromNixMay) l
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromNix v = fromNixMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ Expectation TList v
|
|
||||||
|
|
||||||
instance (Convertible e t f m, FromNix a m (NValue t f m))
|
|
||||||
=> FromNix (HashMap Text a) m (NValue t f m) where
|
|
||||||
fromNixMay = \case
|
|
||||||
NVSet s _ -> sequence <$> traverse (`force` fromNixMay) s
|
|
||||||
_ -> pure Nothing
|
|
||||||
fromNix v = fromNixMay v >>= \case
|
|
||||||
Just b -> pure b
|
|
||||||
_ -> throwError $ Expectation TSet v
|
|
||||||
|
|
||||||
instance Convertible e t f m => FromNix () m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => FromNix () m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Bool m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Bool m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Int m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Int m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Integer m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Integer m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Float m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Float m (NValue t f m) where
|
|
||||||
instance (Convertible e t f m, MonadEffects t f m)
|
|
||||||
=> FromNix NixString m (NValueNF t f m) where
|
|
||||||
instance (Convertible e t f m, MonadEffects t f m)
|
|
||||||
=> FromNix NixString m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => FromNix ByteString m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => FromNix ByteString m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Path m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => FromNix Path m (NValue t f m) where
|
|
||||||
instance (Convertible e t f m, FromValue a m (NValueNF t f m), Show a)
|
|
||||||
=> FromNix [a] m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> FromNix (HashMap Text (NValueNF t f m)) m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> FromNix (HashMap Text (NValueNF t f m),
|
|
||||||
HashMap Text SourcePos) m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> FromNix (HashMap Text t, HashMap Text SourcePos) m (NValue t f m) where
|
|
||||||
|
|
||||||
instance (Monad m, FromNix a m v) => FromNix a m (m v) where
|
|
||||||
fromNixMay = (>>= fromNixMay)
|
|
||||||
fromNix = (>>= fromNix)
|
|
||||||
|
|
||||||
class ToNix a m v where
|
|
||||||
toNix :: a -> m v
|
|
||||||
default toNix :: ToValue a m v => a -> m v
|
|
||||||
toNix = toValue
|
|
||||||
|
|
||||||
instance (Convertible e t f m, ToNix a m (NValue t f m))
|
|
||||||
=> ToNix [a] m (NValue t f m) where
|
|
||||||
toNix = fmap nvList . traverse (thunk . go)
|
|
||||||
where
|
|
||||||
go =
|
|
||||||
(\v -> whileForcingThunk @t @f @m (ConcerningValue v) (pure v)) <=< toNix
|
|
||||||
|
|
||||||
instance (Convertible e t f m, ToNix a m (NValue t f m))
|
|
||||||
=> ToNix (HashMap Text a) m (NValue t f m) where
|
|
||||||
toNix = fmap (flip nvSet M.empty) . traverse (thunk . go)
|
|
||||||
where
|
|
||||||
go =
|
|
||||||
(\v -> whileForcingThunk @t @f @m (ConcerningValue v) (pure v)) <=< toNix
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToNix () m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix () m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Bool m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Bool m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Int m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Int m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Integer m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Integer m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Float m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Float m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => ToNix NixString m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix NixString m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => ToNix ByteString m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix ByteString m (NValue t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Path m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m => ToNix Path m (NValue t f m) where
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> ToNix (HashMap Text (NValueNF t f m)) m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> ToNix (HashMap Text (NValueNF t f m),
|
|
||||||
HashMap Text SourcePos) m (NValueNF t f m) where
|
|
||||||
instance Convertible e t f m
|
|
||||||
=> ToNix (HashMap Text t, HashMap Text SourcePos) m (NValue t f m) where
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToNix Bool m (NExprF r) where
|
|
||||||
toNix = pure . NConstant . NBool
|
|
||||||
|
|
||||||
instance Convertible e t f m => ToNix () m (NExprF r) where
|
|
||||||
toNix _ = pure $ NConstant NNull
|
|
||||||
|
|
||||||
instance (Convertible e t f m, ToNix a m (NValueNF t f m))
|
|
||||||
=> ToNix [a] m (NValueNF t f m) where
|
|
||||||
toNix = fmap nvListNF . traverse toNix
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ class (MonadFile m,
|
||||||
|
|
||||||
-- | Having an explicit list of sets corresponding to the NIX_PATH
|
-- | Having an explicit list of sets corresponding to the NIX_PATH
|
||||||
-- and a file path try to find an existing path
|
-- and a file path try to find an existing path
|
||||||
findPath :: [t] -> FilePath -> m FilePath
|
findPath :: [NValue t f m] -> FilePath -> m FilePath
|
||||||
|
|
||||||
importPath :: FilePath -> m (NValue t f m)
|
importPath :: FilePath -> m (NValue t f m)
|
||||||
pathToDefaultNix :: FilePath -> m FilePath
|
pathToDefaultNix :: FilePath -> m FilePath
|
||||||
|
|
207
src/Nix/Eval.hs
207
src/Nix/Eval.hs
|
@ -38,81 +38,89 @@ import Nix.Frames
|
||||||
import Nix.String
|
import Nix.String
|
||||||
import Nix.Scope
|
import Nix.Scope
|
||||||
import Nix.Strings ( runAntiquoted )
|
import Nix.Strings ( runAntiquoted )
|
||||||
import Nix.Thunk
|
|
||||||
import Nix.Utils
|
import Nix.Utils
|
||||||
|
import Nix.Value.Monad
|
||||||
|
|
||||||
|
-- instance MonadThunk t m (NValue t f m) => MonadValue (NValue t f m) m where
|
||||||
|
-- defer = fmap Pure . thunk
|
||||||
|
-- demand (Pure t) f = force t f
|
||||||
|
-- demand v@(Free _) f = f v
|
||||||
|
|
||||||
class (Show v, Monad m) => MonadEval v m where
|
class (Show v, Monad m) => MonadEval v m where
|
||||||
freeVariable :: Text -> m v
|
freeVariable :: Text -> m v
|
||||||
synHole :: Text -> m v
|
synHole :: Text -> m v
|
||||||
attrMissing :: NonEmpty Text -> Maybe v -> m v
|
attrMissing :: NonEmpty Text -> Maybe v -> m v
|
||||||
evaledSym :: Text -> v -> m v
|
evaledSym :: Text -> v -> m v
|
||||||
evalCurPos :: m v
|
evalCurPos :: m v
|
||||||
evalConstant :: NAtom -> m v
|
evalConstant :: NAtom -> m v
|
||||||
evalString :: NString (m v) -> m v
|
evalString :: NString (m v) -> m v
|
||||||
evalLiteralPath :: FilePath -> m v
|
evalLiteralPath :: FilePath -> m v
|
||||||
evalEnvPath :: FilePath -> m v
|
evalEnvPath :: FilePath -> m v
|
||||||
evalUnary :: NUnaryOp -> v -> m v
|
evalUnary :: NUnaryOp -> v -> m v
|
||||||
evalBinary :: NBinaryOp -> v -> m v -> m v
|
evalBinary :: NBinaryOp -> v -> m v -> m v
|
||||||
-- ^ The second argument is an action because operators such as boolean &&
|
-- ^ The second argument is an action because operators such as boolean &&
|
||||||
-- and || may not evaluate the second argument.
|
-- and || may not evaluate the second argument.
|
||||||
evalWith :: m v -> m v -> m v
|
evalWith :: m v -> m v -> m v
|
||||||
evalIf :: v -> m v -> m v -> m v
|
evalIf :: v -> m v -> m v -> m v
|
||||||
evalAssert :: v -> m v -> m v
|
evalAssert :: v -> m v -> m v
|
||||||
evalApp :: v -> m v -> m v
|
evalApp :: v -> m v -> m v
|
||||||
evalAbs :: Params (m v)
|
evalAbs :: Params (m v)
|
||||||
-> (forall a. m v -> (AttrSet (m v) -> m v -> m (a, v)) -> m (a, v))
|
-> (forall a. m v -> (AttrSet (m v) -> m v -> m (a, v)) -> m (a, v))
|
||||||
-> m v
|
-> m v
|
||||||
{-
|
{-
|
||||||
evalSelect :: v -> NonEmpty Text -> Maybe (m v) -> m v
|
evalSelect :: v -> NonEmpty Text -> Maybe (m v) -> m v
|
||||||
evalHasAttr :: v -> NonEmpty Text -> m v
|
evalHasAttr :: v -> NonEmpty Text -> m v
|
||||||
|
|
||||||
-- | This and the following methods are intended to allow things like
|
-- | This and the following methods are intended to allow things like
|
||||||
-- adding provenance information.
|
-- adding provenance information.
|
||||||
evalListElem :: [m v] -> Int -> m v -> m v
|
evalListElem :: [m v] -> Int -> m v -> m v
|
||||||
evalList :: [t] -> m v
|
evalList :: [v] -> m v
|
||||||
evalSetElem :: AttrSet (m v) -> Text -> m v -> m v
|
evalSetElem :: AttrSet (m v) -> Text -> m v -> m v
|
||||||
evalSet :: AttrSet t -> AttrSet SourcePos -> m v
|
evalSet :: AttrSet v -> AttrSet SourcePos -> m v
|
||||||
evalRecSetElem :: AttrSet (m v) -> Text -> m v -> m v
|
evalRecSetElem :: AttrSet (m v) -> Text -> m v -> m v
|
||||||
evalRecSet :: AttrSet t -> AttrSet SourcePos -> m v
|
evalRecSet :: AttrSet v -> AttrSet SourcePos -> m v
|
||||||
evalLetElem :: Text -> m v -> m v
|
evalLetElem :: Text -> m v -> m v
|
||||||
evalLet :: m v -> m v
|
evalLet :: m v -> m v
|
||||||
-}
|
-}
|
||||||
evalError :: Exception s => s -> m a
|
evalError :: Exception s => s -> m a
|
||||||
|
|
||||||
type MonadNixEval v t m
|
type MonadNixEval v m
|
||||||
= ( MonadEval v m
|
= ( MonadEval v m
|
||||||
, Scoped t m
|
, Scoped v m
|
||||||
, MonadThunk t m v
|
, MonadValue v m
|
||||||
, MonadFix m
|
, MonadFix m
|
||||||
, ToValue Bool m v
|
, ToValue Bool m v
|
||||||
, ToValue [t] m v
|
, ToValue [v] m v
|
||||||
, FromValue NixString m v
|
, FromValue NixString m v
|
||||||
, ToValue (AttrSet t, AttrSet SourcePos) m v
|
, ToValue (AttrSet v, AttrSet SourcePos) m v
|
||||||
, FromValue (AttrSet t, AttrSet SourcePos) m v
|
, FromValue (AttrSet v, AttrSet SourcePos) m v
|
||||||
)
|
)
|
||||||
|
|
||||||
data EvalFrame m t
|
data EvalFrame m v
|
||||||
= EvaluatingExpr (Scopes m t) NExprLoc
|
= EvaluatingExpr (Scopes m v) NExprLoc
|
||||||
| ForcingExpr (Scopes m t) NExprLoc
|
| ForcingExpr (Scopes m v) NExprLoc
|
||||||
| Calling String SrcSpan
|
| Calling String SrcSpan
|
||||||
| SynHole (SynHoleInfo m t)
|
| SynHole (SynHoleInfo m v)
|
||||||
deriving (Show, Typeable)
|
deriving (Show, Typeable)
|
||||||
|
|
||||||
instance (Typeable m, Typeable t) => Exception (EvalFrame m t)
|
instance (Typeable m, Typeable v) => Exception (EvalFrame m v)
|
||||||
|
|
||||||
data SynHoleInfo m t = SynHoleInfo
|
data SynHoleInfo m v = SynHoleInfo
|
||||||
{ _synHoleInfo_expr :: NExprLoc
|
{ _synHoleInfo_expr :: NExprLoc
|
||||||
, _synHoleInfo_scope :: Scopes m t
|
, _synHoleInfo_scope :: Scopes m v
|
||||||
} deriving (Show, Typeable)
|
} deriving (Show, Typeable)
|
||||||
|
|
||||||
instance (Typeable m, Typeable t) => Exception (SynHoleInfo m t)
|
instance (Typeable m, Typeable v) => Exception (SynHoleInfo m v)
|
||||||
|
|
||||||
eval :: forall v t m . MonadNixEval v t m => NExprF (m v) -> m v
|
-- jww (2019-03-18): By deferring only those things which must wait until
|
||||||
|
-- context of us, this can be written as:
|
||||||
|
-- eval :: forall v m . MonadNixEval v m => NExprF v -> m v
|
||||||
|
eval :: forall v m . MonadNixEval v m => NExprF (m v) -> m v
|
||||||
|
|
||||||
eval (NSym "__curPos") = evalCurPos
|
eval (NSym "__curPos") = evalCurPos
|
||||||
|
|
||||||
eval (NSym var ) = (lookupVar var :: m (Maybe t))
|
eval (NSym var ) = (lookupVar var :: m (Maybe v))
|
||||||
>>= maybe (freeVariable var) (force ?? evaledSym var)
|
>>= maybe (freeVariable var) (demand ?? evaledSym var)
|
||||||
|
|
||||||
eval (NConstant x ) = evalConstant x
|
eval (NConstant x ) = evalConstant x
|
||||||
eval (NStr str ) = evalString str
|
eval (NStr str ) = evalString str
|
||||||
|
@ -121,7 +129,7 @@ eval (NEnvPath p ) = evalEnvPath p
|
||||||
eval (NUnary op arg ) = evalUnary op =<< arg
|
eval (NUnary op arg ) = evalUnary op =<< arg
|
||||||
|
|
||||||
eval (NBinary NApp fun arg) = do
|
eval (NBinary NApp fun arg) = do
|
||||||
scope <- currentScopes :: m (Scopes m t)
|
scope <- currentScopes :: m (Scopes m v)
|
||||||
fun >>= (`evalApp` withScopes scope arg)
|
fun >>= (`evalApp` withScopes scope arg)
|
||||||
|
|
||||||
eval (NBinary op larg rarg) = larg >>= evalBinary op ?? rarg
|
eval (NBinary op larg rarg) = larg >>= evalBinary op ?? rarg
|
||||||
|
@ -133,7 +141,7 @@ eval (NHasAttr aset attr) = evalSelect aset attr >>= toValue . isRight
|
||||||
|
|
||||||
eval (NList l ) = do
|
eval (NList l ) = do
|
||||||
scope <- currentScopes
|
scope <- currentScopes
|
||||||
for l (thunk @t @m @v . withScopes @t scope) >>= toValue
|
for l (defer @v @m . withScopes @v scope) >>= toValue
|
||||||
|
|
||||||
eval (NSet binds) =
|
eval (NSet binds) =
|
||||||
evalBinds False (desugarBinds (eval . NSet) binds) >>= toValue
|
evalBinds False (desugarBinds (eval . NSet) binds) >>= toValue
|
||||||
|
@ -154,32 +162,32 @@ eval (NAbs params body) = do
|
||||||
-- needs to be used when evaluating the body and default arguments, hence
|
-- 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
|
-- we defer here so the present scope is restored when the parameters and
|
||||||
-- body are forced during application.
|
-- body are forced during application.
|
||||||
scope <- currentScopes :: m (Scopes m t)
|
scope <- currentScopes :: m (Scopes m v)
|
||||||
evalAbs params $ \arg k -> withScopes scope $ do
|
evalAbs params $ \arg k -> withScopes scope $ do
|
||||||
args <- buildArgument params arg
|
args <- buildArgument params arg
|
||||||
pushScope args (k (M.map (`force` pure) args) body)
|
pushScope args (k (M.map (`demand` pure) args) body)
|
||||||
|
|
||||||
eval (NSynHole name) = synHole name
|
eval (NSynHole name) = synHole name
|
||||||
|
|
||||||
-- | If you know that the 'scope' action will result in an 'AttrSet t', then
|
-- | If you know that the 'scope' action will result in an 'AttrSet v', then
|
||||||
-- this implementation may be used as an implementation for 'evalWith'.
|
-- this implementation may be used as an implementation for 'evalWith'.
|
||||||
evalWithAttrSet :: forall v t m . MonadNixEval v t m => m v -> m v -> m v
|
evalWithAttrSet :: forall v m . MonadNixEval v m => m v -> m v -> m v
|
||||||
evalWithAttrSet aset body = do
|
evalWithAttrSet aset body = do
|
||||||
-- The scope is deliberately wrapped in a thunk here, since it is
|
-- The scope is deliberately wrapped in a thunk here, since it is
|
||||||
-- evaluated each time a name is looked up within the weak scope, and
|
-- evaluated 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
|
-- we want to be sure the action it evaluates is to force a thunk, so
|
||||||
-- its value is only computed once.
|
-- its value is only computed once.
|
||||||
scope <- currentScopes :: m (Scopes m t)
|
scope <- currentScopes :: m (Scopes m v)
|
||||||
s <- thunk @t @m @v $ withScopes scope aset
|
s <- defer @v @m $ withScopes scope aset
|
||||||
pushWeakScope
|
pushWeakScope
|
||||||
?? body
|
?? body
|
||||||
$ force s
|
$ demand s
|
||||||
$ fmap fst
|
$ fmap fst
|
||||||
. fromValue @(AttrSet t, AttrSet SourcePos)
|
. fromValue @(AttrSet v, AttrSet SourcePos)
|
||||||
|
|
||||||
attrSetAlter
|
attrSetAlter
|
||||||
:: forall v t m
|
:: forall v m
|
||||||
. MonadNixEval v t m
|
. MonadNixEval v m
|
||||||
=> [Text]
|
=> [Text]
|
||||||
-> SourcePos
|
-> SourcePos
|
||||||
-> AttrSet (m v)
|
-> AttrSet (m v)
|
||||||
|
@ -196,17 +204,16 @@ attrSetAlter (k : ks) pos m p val = case M.lookup k m of
|
||||||
| null ks
|
| null ks
|
||||||
-> go
|
-> go
|
||||||
| otherwise
|
| otherwise
|
||||||
-> x >>= fromValue @(AttrSet t, AttrSet SourcePos) >>= \(st, sp) ->
|
-> x >>= fromValue @(AttrSet v, AttrSet SourcePos) >>= \(st, sp) ->
|
||||||
recurse (force ?? pure <$> st) sp
|
recurse (demand ?? pure <$> st) sp
|
||||||
where
|
where
|
||||||
go = return (M.insert k val m, M.insert k pos p)
|
go = return (M.insert k val m, M.insert k pos p)
|
||||||
|
|
||||||
recurse st sp = attrSetAlter ks pos st sp val <&> \(st', _) ->
|
recurse st sp = attrSetAlter ks pos st sp val <&> \(st', _) ->
|
||||||
( M.insert
|
( M.insert
|
||||||
k
|
k
|
||||||
( toValue @(AttrSet t, AttrSet SourcePos)
|
( toValue @(AttrSet v, AttrSet SourcePos)
|
||||||
=<< (, mempty)
|
=<< (, mempty)
|
||||||
. fmap wrapValue
|
|
||||||
<$> sequence st'
|
<$> sequence st'
|
||||||
)
|
)
|
||||||
st
|
st
|
||||||
|
@ -240,13 +247,13 @@ desugarBinds embed binds = evalState (mapM (go <=< collect) binds) M.empty
|
||||||
Just (p, v) -> pure $ NamedVar (StaticKey x :| []) (embed v) p
|
Just (p, v) -> pure $ NamedVar (StaticKey x :| []) (embed v) p
|
||||||
|
|
||||||
evalBinds
|
evalBinds
|
||||||
:: forall v t m
|
:: forall v m
|
||||||
. MonadNixEval v t m
|
. MonadNixEval v m
|
||||||
=> Bool
|
=> Bool
|
||||||
-> [Binding (m v)]
|
-> [Binding (m v)]
|
||||||
-> m (AttrSet t, AttrSet SourcePos)
|
-> m (AttrSet v, AttrSet SourcePos)
|
||||||
evalBinds recursive binds = do
|
evalBinds recursive binds = do
|
||||||
scope <- currentScopes :: m (Scopes m t)
|
scope <- currentScopes :: m (Scopes m v)
|
||||||
buildResult scope . concat =<< mapM (go scope) (moveOverridesLast binds)
|
buildResult scope . concat =<< mapM (go scope) (moveOverridesLast binds)
|
||||||
where
|
where
|
||||||
moveOverridesLast = uncurry (++) . partition
|
moveOverridesLast = uncurry (++) . partition
|
||||||
|
@ -255,12 +262,12 @@ evalBinds recursive binds = do
|
||||||
_ -> True
|
_ -> True
|
||||||
)
|
)
|
||||||
|
|
||||||
go :: Scopes m t -> Binding (m v) -> m [([Text], SourcePos, m v)]
|
go :: Scopes m v -> Binding (m v) -> m [([Text], SourcePos, m v)]
|
||||||
go _ (NamedVar (StaticKey "__overrides" :| []) finalValue pos) =
|
go _ (NamedVar (StaticKey "__overrides" :| []) finalValue pos) =
|
||||||
finalValue >>= fromValue >>= \(o', p') ->
|
finalValue >>= fromValue >>= \(o', p') ->
|
||||||
-- jww (2018-05-09): What to do with the key position here?
|
-- jww (2018-05-09): What to do with the key position here?
|
||||||
return $ map
|
return $ map
|
||||||
(\(k, v) -> ([k], fromMaybe pos (M.lookup k p'), force @t @m @v v pure))
|
(\(k, v) -> ([k], fromMaybe pos (M.lookup k p'), demand @v @m v pure))
|
||||||
(M.toList o')
|
(M.toList o')
|
||||||
|
|
||||||
go _ (NamedVar pathExpr finalValue pos) = do
|
go _ (NamedVar pathExpr finalValue pos) = do
|
||||||
|
@ -271,7 +278,7 @@ evalBinds recursive binds = do
|
||||||
pure
|
pure
|
||||||
( []
|
( []
|
||||||
, nullPos
|
, nullPos
|
||||||
, toValue @(AttrSet t, AttrSet SourcePos) (mempty, mempty)
|
, toValue @(AttrSet v, AttrSet SourcePos) (mempty, mempty)
|
||||||
)
|
)
|
||||||
Just k -> case t of
|
Just k -> case t of
|
||||||
[] -> pure ([k], pos, finalValue)
|
[] -> pure ([k], pos, finalValue)
|
||||||
|
@ -294,31 +301,31 @@ evalBinds recursive binds = do
|
||||||
mv <- case ms of
|
mv <- case ms of
|
||||||
Nothing -> withScopes scope $ lookupVar key
|
Nothing -> withScopes scope $ lookupVar key
|
||||||
Just s ->
|
Just s ->
|
||||||
s >>= fromValue @(AttrSet t, AttrSet SourcePos) >>= \(s, _) ->
|
s >>= fromValue @(AttrSet v, AttrSet SourcePos) >>= \(s, _) ->
|
||||||
clearScopes @t $ pushScope s $ lookupVar key
|
clearScopes @v $ pushScope s $ lookupVar key
|
||||||
case mv of
|
case mv of
|
||||||
Nothing -> attrMissing (key :| []) Nothing
|
Nothing -> attrMissing (key :| []) Nothing
|
||||||
Just v -> force v pure
|
Just v -> demand v pure
|
||||||
)
|
)
|
||||||
|
|
||||||
buildResult
|
buildResult
|
||||||
:: Scopes m t
|
:: Scopes m v
|
||||||
-> [([Text], SourcePos, m v)]
|
-> [([Text], SourcePos, m v)]
|
||||||
-> m (AttrSet t, AttrSet SourcePos)
|
-> m (AttrSet v, AttrSet SourcePos)
|
||||||
buildResult scope bindings = do
|
buildResult scope bindings = do
|
||||||
(s, p) <- foldM insert (M.empty, M.empty) bindings
|
(s, p) <- foldM insert (M.empty, M.empty) bindings
|
||||||
res <- if recursive then loebM (encapsulate <$> s) else traverse mkThunk s
|
res <- if recursive then loebM (encapsulate <$> s) else traverse mkThunk s
|
||||||
return (res, p)
|
return (res, p)
|
||||||
where
|
where
|
||||||
mkThunk = thunk . withScopes scope
|
mkThunk = defer . withScopes scope
|
||||||
|
|
||||||
encapsulate f attrs = mkThunk . pushScope attrs $ f
|
encapsulate f attrs = mkThunk . pushScope attrs $ f
|
||||||
|
|
||||||
insert (m, p) (path, pos, value) = attrSetAlter path pos m p value
|
insert (m, p) (path, pos, value) = attrSetAlter path pos m p value
|
||||||
|
|
||||||
evalSelect
|
evalSelect
|
||||||
:: forall v t m
|
:: forall v m
|
||||||
. MonadNixEval v t m
|
. MonadNixEval v m
|
||||||
=> m v
|
=> m v
|
||||||
-> NAttrPath (m v)
|
-> NAttrPath (m v)
|
||||||
-> m (Either (v, NonEmpty Text) (m v))
|
-> m (Either (v, NonEmpty Text) (m v))
|
||||||
|
@ -328,10 +335,10 @@ evalSelect aset attr = do
|
||||||
extract s path
|
extract s path
|
||||||
where
|
where
|
||||||
extract x path@(k :| ks) = fromValueMay x >>= \case
|
extract x path@(k :| ks) = fromValueMay x >>= \case
|
||||||
Just (s :: AttrSet t, p :: AttrSet SourcePos)
|
Just (s :: AttrSet v, p :: AttrSet SourcePos)
|
||||||
| Just t <- M.lookup k s -> case ks of
|
| Just t <- M.lookup k s -> case ks of
|
||||||
[] -> pure $ Right $ force t pure
|
[] -> pure $ Right $ demand t pure
|
||||||
y : ys -> force t $ extract ?? (y :| ys)
|
y : ys -> demand t $ extract ?? (y :| ys)
|
||||||
| otherwise -> Left . (, path) <$> toValue (s, p)
|
| otherwise -> Left . (, path) <$> toValue (s, p)
|
||||||
Nothing -> return $ Left (x, path)
|
Nothing -> return $ Left (x, path)
|
||||||
|
|
||||||
|
@ -376,16 +383,16 @@ assembleString = \case
|
||||||
(>>= fromValueMay)
|
(>>= fromValueMay)
|
||||||
|
|
||||||
buildArgument
|
buildArgument
|
||||||
:: forall v t m . MonadNixEval v t m => Params (m v) -> m v -> m (AttrSet t)
|
:: forall v m . MonadNixEval v m => Params (m v) -> m v -> m (AttrSet v)
|
||||||
buildArgument params arg = do
|
buildArgument params arg = do
|
||||||
scope <- currentScopes :: m (Scopes m t)
|
scope <- currentScopes :: m (Scopes m v)
|
||||||
case params of
|
case params of
|
||||||
Param name -> M.singleton name <$> thunk (withScopes scope arg)
|
Param name -> M.singleton name <$> defer (withScopes scope arg)
|
||||||
ParamSet s isVariadic m ->
|
ParamSet s isVariadic m ->
|
||||||
arg >>= fromValue @(AttrSet t, AttrSet SourcePos) >>= \(args, _) -> do
|
arg >>= fromValue @(AttrSet v, AttrSet SourcePos) >>= \(args, _) -> do
|
||||||
let inject = case m of
|
let inject = case m of
|
||||||
Nothing -> id
|
Nothing -> id
|
||||||
Just n -> M.insert n $ const $ thunk (withScopes scope arg)
|
Just n -> M.insert n $ const $ defer (withScopes scope arg)
|
||||||
loebM
|
loebM
|
||||||
(inject $ M.mapMaybe id $ alignWithKey (assemble scope isVariadic)
|
(inject $ M.mapMaybe id $ alignWithKey (assemble scope isVariadic)
|
||||||
args
|
args
|
||||||
|
@ -393,11 +400,11 @@ buildArgument params arg = do
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
assemble
|
assemble
|
||||||
:: Scopes m t
|
:: Scopes m v
|
||||||
-> Bool
|
-> Bool
|
||||||
-> Text
|
-> Text
|
||||||
-> These t (Maybe (m v))
|
-> These v (Maybe (m v))
|
||||||
-> Maybe (AttrSet t -> m t)
|
-> Maybe (AttrSet v -> m v)
|
||||||
assemble scope isVariadic k = \case
|
assemble scope isVariadic k = \case
|
||||||
That Nothing ->
|
That Nothing ->
|
||||||
Just
|
Just
|
||||||
|
@ -407,7 +414,7 @@ buildArgument params arg = do
|
||||||
$ "Missing value for parameter: "
|
$ "Missing value for parameter: "
|
||||||
++ show k
|
++ show k
|
||||||
That (Just f) ->
|
That (Just f) ->
|
||||||
Just $ \args -> thunk $ withScopes scope $ pushScope args f
|
Just $ \args -> defer $ withScopes scope $ pushScope args f
|
||||||
This _
|
This _
|
||||||
| isVariadic
|
| isVariadic
|
||||||
-> Nothing
|
-> Nothing
|
||||||
|
@ -426,17 +433,17 @@ addSourcePositions f v@(Fix (Compose (Ann ann _))) =
|
||||||
local (set hasLens ann) (f v)
|
local (set hasLens ann) (f v)
|
||||||
|
|
||||||
addStackFrames
|
addStackFrames
|
||||||
:: forall t e m a
|
:: forall v e m a
|
||||||
. (Scoped t m, Framed e m, Typeable t, Typeable m)
|
. (Scoped v m, Framed e m, Typeable v, Typeable m)
|
||||||
=> Transform NExprLocF (m a)
|
=> Transform NExprLocF (m a)
|
||||||
addStackFrames f v = do
|
addStackFrames f v = do
|
||||||
scopes <- currentScopes :: m (Scopes m t)
|
scopes <- currentScopes :: m (Scopes m v)
|
||||||
withFrame Info (EvaluatingExpr scopes v) (f v)
|
withFrame Info (EvaluatingExpr scopes v) (f v)
|
||||||
|
|
||||||
framedEvalExprLoc
|
framedEvalExprLoc
|
||||||
:: forall t e v m
|
:: forall e v m
|
||||||
. (MonadNixEval v t m, Framed e m, Has e SrcSpan, Typeable t, Typeable m)
|
. (MonadNixEval v m, Framed e m, Has e SrcSpan, Typeable m, Typeable v)
|
||||||
=> NExprLoc
|
=> NExprLoc
|
||||||
-> m v
|
-> m v
|
||||||
framedEvalExprLoc =
|
framedEvalExprLoc =
|
||||||
adi (eval . annotated . getCompose) (addStackFrames @t . addSourcePositions)
|
adi (eval . annotated . getCompose) (addStackFrames @v . addSourcePositions)
|
||||||
|
|
150
src/Nix/Exec.hs
150
src/Nix/Exec.hs
|
@ -35,6 +35,7 @@ import Control.Applicative
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Catch hiding ( catchJust )
|
import Control.Monad.Catch hiding ( catchJust )
|
||||||
import Control.Monad.Fix
|
import Control.Monad.Fix
|
||||||
|
import Control.Monad.Free
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Ref
|
import Control.Monad.Ref
|
||||||
import Control.Monad.State.Strict
|
import Control.Monad.State.Strict
|
||||||
|
@ -71,6 +72,7 @@ import Nix.Thunk
|
||||||
import Nix.Utils
|
import Nix.Utils
|
||||||
import Nix.Value
|
import Nix.Value
|
||||||
import Nix.Value.Equal
|
import Nix.Value.Equal
|
||||||
|
import Nix.Value.Monad
|
||||||
#ifdef MIN_VERSION_haskeline
|
#ifdef MIN_VERSION_haskeline
|
||||||
import System.Console.Haskeline.MonadException hiding(catch)
|
import System.Console.Haskeline.MonadException hiding(catch)
|
||||||
#endif
|
#endif
|
||||||
|
@ -86,64 +88,69 @@ import GHC.DataSize
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
type MonadCited t f m
|
type MonadCited t f m
|
||||||
= (HasCitations1 t m (NValue t f m) f, MonadDataContext f m)
|
= ( HasCitations m (NValue t f m) t
|
||||||
|
, HasCitations1 m (NValue t f m) f
|
||||||
|
, MonadDataContext f m
|
||||||
|
)
|
||||||
|
|
||||||
nvConstantP
|
nvConstantP
|
||||||
:: MonadCited t f m => Provenance t m (NValue t f m) -> NAtom -> NValue t f m
|
:: MonadCited t f m => Provenance m (NValue t f m) -> NAtom -> NValue t f m
|
||||||
nvConstantP p x = addProvenance p (nvConstant x)
|
nvConstantP p x = addProvenance p (nvConstant x)
|
||||||
|
|
||||||
nvStrP
|
nvStrP
|
||||||
:: MonadCited t f m
|
:: MonadCited t f m
|
||||||
=> Provenance t m (NValue t f m)
|
=> Provenance m (NValue t f m)
|
||||||
-> NixString
|
-> NixString
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
nvStrP p ns = addProvenance p (nvStr ns)
|
nvStrP p ns = addProvenance p (nvStr ns)
|
||||||
|
|
||||||
nvPathP
|
nvPathP
|
||||||
:: MonadCited t f m
|
:: MonadCited t f m
|
||||||
=> Provenance t m (NValue t f m)
|
=> Provenance m (NValue t f m)
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
nvPathP p x = addProvenance p (nvPath x)
|
nvPathP p x = addProvenance p (nvPath x)
|
||||||
|
|
||||||
nvListP
|
nvListP :: MonadCited t f m
|
||||||
:: MonadCited t f m => Provenance t m (NValue t f m) -> [t] -> NValue t f m
|
=> Provenance m (NValue t f m) -> [NValue t f m] -> NValue t f m
|
||||||
nvListP p l = addProvenance p (nvList l)
|
nvListP p l = addProvenance p (nvList l)
|
||||||
|
|
||||||
nvSetP
|
nvSetP
|
||||||
:: MonadCited t f m
|
:: MonadCited t f m
|
||||||
=> Provenance t m (NValue t f m)
|
=> Provenance m (NValue t f m)
|
||||||
-> AttrSet t
|
-> AttrSet (NValue t f m)
|
||||||
-> AttrSet SourcePos
|
-> AttrSet SourcePos
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
nvSetP p s x = addProvenance p (nvSet s x)
|
nvSetP p s x = addProvenance p (nvSet s x)
|
||||||
|
|
||||||
nvClosureP
|
nvClosureP
|
||||||
:: MonadCited t f m
|
:: MonadCited t f m
|
||||||
=> Provenance t m (NValue t f m)
|
=> Provenance m (NValue t f m)
|
||||||
-> Params ()
|
-> Params ()
|
||||||
-> (m (NValue t f m) -> m t)
|
-> (NValue t f m -> m (NValue t f m))
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
nvClosureP p x f = addProvenance p (nvClosure x f)
|
nvClosureP p x f = addProvenance p (nvClosure x f)
|
||||||
|
|
||||||
nvBuiltinP
|
nvBuiltinP
|
||||||
:: MonadCited t f m
|
:: MonadCited t f m
|
||||||
=> Provenance t m (NValue t f m)
|
=> Provenance m (NValue t f m)
|
||||||
-> String
|
-> String
|
||||||
-> (m (NValue t f m) -> m t)
|
-> (NValue t f m -> m (NValue t f m))
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
nvBuiltinP p name f = addProvenance p (nvBuiltin name f)
|
nvBuiltinP p name f = addProvenance p (nvBuiltin name f)
|
||||||
|
|
||||||
type MonadCitedThunks t f m
|
type MonadCitedThunks t f m
|
||||||
= ( MonadThunk t m (NValue t f m)
|
= ( MonadValue (NValue t f m) m
|
||||||
|
, MonadThunk t m (NValue t f m)
|
||||||
, MonadDataErrorContext t f m
|
, MonadDataErrorContext t f m
|
||||||
, HasCitations1 t m (NValue t f m) f
|
, HasCitations m (NValue t f m) t
|
||||||
|
, HasCitations1 m (NValue t f m) f
|
||||||
)
|
)
|
||||||
|
|
||||||
type MonadNix e t f m
|
type MonadNix e t f m
|
||||||
= ( Has e SrcSpan
|
= ( Has e SrcSpan
|
||||||
, Has e Options
|
, Has e Options
|
||||||
, Scoped t m
|
, Scoped (NValue t f m) m
|
||||||
, Framed e m
|
, Framed e m
|
||||||
, MonadFix m
|
, MonadFix m
|
||||||
, MonadCatch m
|
, MonadCatch m
|
||||||
|
@ -151,6 +158,7 @@ type MonadNix e t f m
|
||||||
, Alternative m
|
, Alternative m
|
||||||
, MonadEffects t f m
|
, MonadEffects t f m
|
||||||
, MonadCitedThunks t f m
|
, MonadCitedThunks t f m
|
||||||
|
, MonadValue (NValue t f m) m
|
||||||
)
|
)
|
||||||
|
|
||||||
data ExecFrame t f m = Assertion SrcSpan (NValue t f m)
|
data ExecFrame t f m = Assertion SrcSpan (NValue t f m)
|
||||||
|
@ -288,7 +296,7 @@ instance MonadNix e t f m => MonadEval (NValue t f m) m where
|
||||||
scope <- currentScopes
|
scope <- currentScopes
|
||||||
span <- currentPos
|
span <- currentPos
|
||||||
addProvenance (Provenance scope (NBinary_ span NApp (Just f) Nothing))
|
addProvenance (Provenance scope (NBinary_ span NApp (Just f) Nothing))
|
||||||
<$> callFunc f x
|
<$> (callFunc f =<< defer x)
|
||||||
|
|
||||||
evalAbs p k = do
|
evalAbs p k = do
|
||||||
scope <- currentScopes
|
scope <- currentScopes
|
||||||
|
@ -296,7 +304,7 @@ instance MonadNix e t f m => MonadEval (NValue t f m) m where
|
||||||
pure $ nvClosureP
|
pure $ nvClosureP
|
||||||
(Provenance scope (NAbs_ span (Nothing <$ p) Nothing))
|
(Provenance scope (NAbs_ span (Nothing <$ p) Nothing))
|
||||||
(void p)
|
(void p)
|
||||||
(\arg -> wrapValue . snd <$> k arg (\_ b -> ((), ) <$> b))
|
(\arg -> snd <$> k (pure arg) (\_ b -> ((), ) <$> b))
|
||||||
|
|
||||||
evalError = throwError
|
evalError = throwError
|
||||||
|
|
||||||
|
@ -305,27 +313,27 @@ callFunc
|
||||||
:: forall e t f m
|
:: forall e t f m
|
||||||
. MonadNix e t f m
|
. MonadNix e t f m
|
||||||
=> NValue t f m
|
=> NValue t f m
|
||||||
|
-> NValue t f m
|
||||||
-> m (NValue t f m)
|
-> m (NValue t f m)
|
||||||
-> m (NValue t f m)
|
callFunc fun arg = demand fun $ \fun' -> do
|
||||||
callFunc fun arg = do
|
|
||||||
frames :: Frames <- asks (view hasLens)
|
frames :: Frames <- asks (view hasLens)
|
||||||
when (length frames > 2000) $ throwError $ ErrorCall
|
when (length frames > 2000) $ throwError $ ErrorCall
|
||||||
"Function call stack exhausted"
|
"Function call stack exhausted"
|
||||||
case fun of
|
case fun' of
|
||||||
NVClosure params f -> do
|
NVClosure params f -> do
|
||||||
traceM $ "callFunc:NVFunction taking " ++ show params
|
traceM $ "callFunc:NVFunction taking " ++ show params
|
||||||
force ?? pure =<< f arg
|
f arg
|
||||||
NVBuiltin name f -> do
|
NVBuiltin name f -> do
|
||||||
span <- currentPos
|
span <- currentPos
|
||||||
force ?? pure =<< withFrame Info (Calling @m @t name span) (f arg)
|
withFrame Info (Calling @m @t name span) (f arg)
|
||||||
s@(NVSet m _) | Just f <- M.lookup "__functor" m -> do
|
s@(NVSet m _) | Just f <- M.lookup "__functor" m -> do
|
||||||
traceM "callFunc:__functor"
|
traceM "callFunc:__functor"
|
||||||
force f $ (`callFunc` pure s) >=> (`callFunc` arg)
|
demand f $ (`callFunc` s) >=> (`callFunc` arg)
|
||||||
x -> throwError $ ErrorCall $ "Attempt to call non-function: " ++ show x
|
x -> throwError $ ErrorCall $ "Attempt to call non-function: " ++ show x
|
||||||
|
|
||||||
execUnaryOp
|
execUnaryOp
|
||||||
:: (Framed e m, MonadCited t f m, Show t)
|
:: (Framed e m, MonadCited t f m, Show t)
|
||||||
=> Scopes m t
|
=> Scopes m (NValue t f m)
|
||||||
-> SrcSpan
|
-> SrcSpan
|
||||||
-> NUnaryOp
|
-> NUnaryOp
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
|
@ -354,23 +362,23 @@ execUnaryOp scope span op arg = do
|
||||||
execBinaryOp
|
execBinaryOp
|
||||||
:: forall e t f m
|
:: forall e t f m
|
||||||
. (MonadNix e t f m, MonadEval (NValue t f m) m)
|
. (MonadNix e t f m, MonadEval (NValue t f m) m)
|
||||||
=> Scopes m t
|
=> Scopes m (NValue t f m)
|
||||||
-> SrcSpan
|
-> SrcSpan
|
||||||
-> NBinaryOp
|
-> NBinaryOp
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
-> m (NValue t f m)
|
-> m (NValue t f m)
|
||||||
-> m (NValue t f m)
|
-> m (NValue t f m)
|
||||||
|
|
||||||
execBinaryOp scope span NOr larg rarg = fromNix larg >>= \l -> if l
|
execBinaryOp scope span NOr larg rarg = fromValue larg >>= \l -> if l
|
||||||
then orOp Nothing True
|
then orOp Nothing True
|
||||||
else rarg >>= \rval -> fromNix @Bool rval >>= orOp (Just rval)
|
else rarg >>= \rval -> fromValue @Bool rval >>= orOp (Just rval)
|
||||||
where
|
where
|
||||||
orOp r b = pure $ nvConstantP
|
orOp r b = pure $ nvConstantP
|
||||||
(Provenance scope (NBinary_ span NOr (Just larg) r))
|
(Provenance scope (NBinary_ span NOr (Just larg) r))
|
||||||
(NBool b)
|
(NBool b)
|
||||||
|
|
||||||
execBinaryOp scope span NAnd larg rarg = fromNix larg >>= \l -> if l
|
execBinaryOp scope span NAnd larg rarg = fromValue larg >>= \l -> if l
|
||||||
then rarg >>= \rval -> fromNix @Bool rval >>= andOp (Just rval)
|
then rarg >>= \rval -> fromValue @Bool rval >>= andOp (Just rval)
|
||||||
else andOp Nothing False
|
else andOp Nothing False
|
||||||
where
|
where
|
||||||
andOp r b = pure $ nvConstantP
|
andOp r b = pure $ nvConstantP
|
||||||
|
@ -379,7 +387,7 @@ execBinaryOp scope span NAnd larg rarg = fromNix larg >>= \l -> if l
|
||||||
|
|
||||||
execBinaryOp scope span op lval rarg = do
|
execBinaryOp scope span op lval rarg = do
|
||||||
rval <- rarg
|
rval <- rarg
|
||||||
let bin :: (Provenance t m (NValue t f m) -> a) -> a
|
let bin :: (Provenance m (NValue t f m) -> a) -> a
|
||||||
bin f = f (Provenance scope (NBinary_ span op (Just lval) (Just rval)))
|
bin f = f (Provenance scope (NBinary_ span op (Just lval) (Just rval)))
|
||||||
toBool = pure . bin nvConstantP . NBool
|
toBool = pure . bin nvConstantP . NBool
|
||||||
case (lval, rval) of
|
case (lval, rval) of
|
||||||
|
@ -499,7 +507,7 @@ execBinaryOp scope span op lval rarg = do
|
||||||
++ show rval
|
++ show rval
|
||||||
|
|
||||||
numBinOp
|
numBinOp
|
||||||
:: (forall r . (Provenance t m (NValue t f m) -> r) -> r)
|
:: (forall r . (Provenance m (NValue t f m) -> r) -> r)
|
||||||
-> (forall a . Num a => a -> a -> a)
|
-> (forall a . Num a => a -> a -> a)
|
||||||
-> NAtom
|
-> NAtom
|
||||||
-> NAtom
|
-> NAtom
|
||||||
|
@ -507,7 +515,7 @@ execBinaryOp scope span op lval rarg = do
|
||||||
numBinOp bin f = numBinOp' bin f f
|
numBinOp bin f = numBinOp' bin f f
|
||||||
|
|
||||||
numBinOp'
|
numBinOp'
|
||||||
:: (forall r . (Provenance t m (NValue t f m) -> r) -> r)
|
:: (forall r . (Provenance m (NValue t f m) -> r) -> r)
|
||||||
-> (Integer -> Integer -> Integer)
|
-> (Integer -> Integer -> Integer)
|
||||||
-> (Float -> Float -> Float)
|
-> (Float -> Float -> Float)
|
||||||
-> NAtom
|
-> NAtom
|
||||||
|
@ -565,12 +573,12 @@ coerceToString ctsm clevel = go
|
||||||
| ctsm == CopyToStore -> storePathToNixString <$> addPath p
|
| ctsm == CopyToStore -> storePathToNixString <$> addPath p
|
||||||
| otherwise -> pure $ principledMakeNixStringWithoutContext $ Text.pack p
|
| otherwise -> pure $ principledMakeNixStringWithoutContext $ Text.pack p
|
||||||
NVList l | clevel == CoerceAny ->
|
NVList l | clevel == CoerceAny ->
|
||||||
nixStringUnwords <$> traverse (`force` go) l
|
nixStringUnwords <$> traverse (`demand` go) l
|
||||||
|
|
||||||
v@(NVSet s _) | Just p <- M.lookup "__toString" s ->
|
v@(NVSet s _) | Just p <- M.lookup "__toString" s ->
|
||||||
force p $ (`callFunc` pure v) >=> go
|
demand p $ (`callFunc` v) >=> go
|
||||||
|
|
||||||
NVSet s _ | Just p <- M.lookup "outPath" s -> force p go
|
NVSet s _ | Just p <- M.lookup "outPath" s -> demand p go
|
||||||
|
|
||||||
v -> throwError $ ErrorCall $ "Expected a string, but saw: " ++ show v
|
v -> throwError $ ErrorCall $ "Expected a string, but saw: " ++ show v
|
||||||
|
|
||||||
|
@ -588,7 +596,7 @@ fromStringNoContext ns = case principledGetStringNoContext ns of
|
||||||
Nothing -> throwError $ ErrorCall "expected string with no context"
|
Nothing -> throwError $ ErrorCall "expected string with no context"
|
||||||
|
|
||||||
newtype Lazy t (f :: * -> *) m a = Lazy
|
newtype Lazy t (f :: * -> *) m a = Lazy
|
||||||
{ runLazy :: ReaderT (Context (Lazy t f m) t)
|
{ runLazy :: ReaderT (Context (Lazy t f m) (NValue t f (Lazy t f m)))
|
||||||
(StateT (HashMap FilePath NExprLoc) m) a }
|
(StateT (HashMap FilePath NExprLoc) m) a }
|
||||||
deriving
|
deriving
|
||||||
( Functor
|
( Functor
|
||||||
|
@ -600,7 +608,7 @@ newtype Lazy t (f :: * -> *) m a = Lazy
|
||||||
, MonadIO
|
, MonadIO
|
||||||
, MonadCatch
|
, MonadCatch
|
||||||
, MonadThrow
|
, MonadThrow
|
||||||
, MonadReader (Context (Lazy t f m) t)
|
, MonadReader (Context (Lazy t f m) (NValue t f (Lazy t f m)))
|
||||||
)
|
)
|
||||||
|
|
||||||
instance MonadTrans (Lazy t f) where
|
instance MonadTrans (Lazy t f) where
|
||||||
|
@ -662,7 +670,7 @@ instance ( MonadFix m
|
||||||
mres <- lookupVar "__cur_file"
|
mres <- lookupVar "__cur_file"
|
||||||
case mres of
|
case mres of
|
||||||
Nothing -> getCurrentDirectory
|
Nothing -> getCurrentDirectory
|
||||||
Just v -> force v $ \case
|
Just v -> demand v $ \case
|
||||||
NVPath s -> return $ takeDirectory s
|
NVPath s -> return $ takeDirectory s
|
||||||
v ->
|
v ->
|
||||||
throwError
|
throwError
|
||||||
|
@ -699,17 +707,18 @@ instance ( MonadFix m
|
||||||
Lazy $ ReaderT $ const $ modify (M.insert path expr)
|
Lazy $ ReaderT $ const $ modify (M.insert path expr)
|
||||||
pure expr
|
pure expr
|
||||||
|
|
||||||
derivationStrict = fromValue @(AttrSet t) >=> \s -> do
|
derivationStrict = fromValue @(AttrSet (NValue t f (Lazy t f m))) >=> \s -> do
|
||||||
nn <- maybe (pure False) (force ?? fromNix) (M.lookup "__ignoreNulls" s)
|
nn <- maybe (pure False) (force ?? fromValue) (M.lookup "__ignoreNulls" s)
|
||||||
s' <- M.fromList <$> mapMaybeM (handleEntry nn) (M.toList s)
|
s' <- M.fromList <$> mapMaybeM (handleEntry nn) (M.toList s)
|
||||||
v' <- normalForm =<< toValue @(AttrSet t) @_ @(NValue t f (Lazy t f m)) s'
|
v' <- normalForm =<< toValue @(AttrSet (NValue t f (Lazy t f m))) @_ @(NValue t f (Lazy t f m)) s'
|
||||||
nixInstantiateExpr $ "derivationStrict " ++ show (prettyNValueNF v')
|
nixInstantiateExpr $ "derivationStrict " ++ show (prettyNValueNF v')
|
||||||
where
|
where
|
||||||
mapMaybeM :: (a -> Lazy t f m (Maybe b)) -> [a] -> Lazy t f m [b]
|
mapMaybeM :: (a -> Lazy t f m (Maybe b)) -> [a] -> Lazy t f m [b]
|
||||||
mapMaybeM op = foldr f (return [])
|
mapMaybeM op = foldr f (return [])
|
||||||
where f x xs = op x >>= (<$> xs) . (++) . maybeToList
|
where f x xs = op x >>= (<$> xs) . (++) . maybeToList
|
||||||
|
|
||||||
handleEntry :: Bool -> (Text, t) -> Lazy t f m (Maybe (Text, t))
|
handleEntry :: Bool -> (Text, NValue t f (Lazy t f m))
|
||||||
|
-> Lazy t f m (Maybe (Text, NValue t f (Lazy t f m)))
|
||||||
handleEntry ignoreNulls (k, v) = fmap (k, ) <$> case k of
|
handleEntry ignoreNulls (k, v) = fmap (k, ) <$> case k of
|
||||||
-- The `args' attribute is special: it supplies the command-line
|
-- The `args' attribute is special: it supplies the command-line
|
||||||
-- arguments to the builder.
|
-- arguments to the builder.
|
||||||
|
@ -721,16 +730,15 @@ instance ( MonadFix m
|
||||||
NVConstant NNull | ignoreNulls -> pure Nothing
|
NVConstant NNull | ignoreNulls -> pure Nothing
|
||||||
v' -> Just <$> coerceNix v'
|
v' -> Just <$> coerceNix v'
|
||||||
where
|
where
|
||||||
coerceNix :: NValue t f (Lazy t f m) -> Lazy t f m t
|
coerceNix :: NValue t f (Lazy t f m) -> Lazy t f m (NValue t f (Lazy t f m))
|
||||||
coerceNix =
|
coerceNix = toValue <=< coerceToString CopyToStore CoerceAny
|
||||||
fmap wrapValue . toNix <=< coerceToString CopyToStore CoerceAny
|
|
||||||
|
|
||||||
coerceNixList :: NValue t f (Lazy t f m) -> Lazy t f m t
|
coerceNixList :: NValue t f (Lazy t f m) -> Lazy t f m (NValue t f (Lazy t f m))
|
||||||
coerceNixList v = do
|
coerceNixList v = do
|
||||||
xs :: [t] <- fromValue @[t] v
|
xs :: [NValue t f (Lazy t f m)] <- fromValue @[NValue t f (Lazy t f m)] v
|
||||||
ys :: [t] <- traverse (\x -> force x coerceNix) xs
|
ys :: [NValue t f (Lazy t f m)] <- traverse (\x -> demand x coerceNix) xs
|
||||||
v' :: NValue t f (Lazy t f m) <- toValue @[t] ys
|
v' :: NValue t f (Lazy t f m) <- toValue @[NValue t f (Lazy t f m)] ys
|
||||||
return $ wrapValue v'
|
return v'
|
||||||
|
|
||||||
traceEffect = putStrLn
|
traceEffect = putStrLn
|
||||||
|
|
||||||
|
@ -775,7 +783,7 @@ findPathBy
|
||||||
:: forall e t f m
|
:: forall e t f m
|
||||||
. MonadNix e t f m
|
. MonadNix e t f m
|
||||||
=> (FilePath -> m (Maybe FilePath))
|
=> (FilePath -> m (Maybe FilePath))
|
||||||
-> [t]
|
-> [NValue t f m]
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> m FilePath
|
-> m FilePath
|
||||||
findPathBy finder l name = do
|
findPathBy finder l name = do
|
||||||
|
@ -790,13 +798,13 @@ findPathBy finder l name = do
|
||||||
++ " (add it using $NIX_PATH or -I)"
|
++ " (add it using $NIX_PATH or -I)"
|
||||||
Just path -> return path
|
Just path -> return path
|
||||||
where
|
where
|
||||||
go :: Maybe FilePath -> t -> m (Maybe FilePath)
|
go :: Maybe FilePath -> NValue t f m -> m (Maybe FilePath)
|
||||||
go p@(Just _) _ = pure p
|
go p@(Just _) _ = pure p
|
||||||
go Nothing l = force l $ fromValue >=> \(s :: HashMap Text t) -> do
|
go Nothing l = demand l $ fromValue >=> \(s :: HashMap Text (NValue t f m)) -> do
|
||||||
p <- resolvePath s
|
p <- resolvePath s
|
||||||
force p $ fromValue >=> \(Path path) -> case M.lookup "prefix" s of
|
demand p $ fromValue >=> \(Path path) -> case M.lookup "prefix" s of
|
||||||
Nothing -> tryPath path Nothing
|
Nothing -> tryPath path Nothing
|
||||||
Just pf -> force pf $ fromValueMay >=> \case
|
Just pf -> demand pf $ fromValueMay >=> \case
|
||||||
Just (nsPfx :: NixString) ->
|
Just (nsPfx :: NixString) ->
|
||||||
let pfx = hackyStringIgnoreContext nsPfx
|
let pfx = hackyStringIgnoreContext nsPfx
|
||||||
in if not (Text.null pfx)
|
in if not (Text.null pfx)
|
||||||
|
@ -811,7 +819,7 @@ findPathBy finder l name = do
|
||||||
resolvePath s = case M.lookup "path" s of
|
resolvePath s = case M.lookup "path" s of
|
||||||
Just t -> return t
|
Just t -> return t
|
||||||
Nothing -> case M.lookup "uri" s of
|
Nothing -> case M.lookup "uri" s of
|
||||||
Just ut -> thunk $ fetchTarball (force ut pure)
|
Just ut -> defer $ fetchTarball (demand ut pure)
|
||||||
Nothing ->
|
Nothing ->
|
||||||
throwError
|
throwError
|
||||||
$ ErrorCall
|
$ ErrorCall
|
||||||
|
@ -819,7 +827,8 @@ findPathBy finder l name = do
|
||||||
++ " with 'path' elements, but saw: "
|
++ " with 'path' elements, but saw: "
|
||||||
++ show s
|
++ show s
|
||||||
|
|
||||||
findPathM :: forall e t f m . MonadNix e t f m => [t] -> FilePath -> m FilePath
|
findPathM :: forall e t f m . MonadNix e t f m
|
||||||
|
=> [NValue t f m] -> FilePath -> m FilePath
|
||||||
findPathM l name = findPathBy path l name
|
findPathM l name = findPathBy path l name
|
||||||
where
|
where
|
||||||
path :: MonadEffects t f m => FilePath -> m (Maybe FilePath)
|
path :: MonadEffects t f m => FilePath -> m (Maybe FilePath)
|
||||||
|
@ -833,8 +842,8 @@ findEnvPathM name = do
|
||||||
mres <- lookupVar "__nixPath"
|
mres <- lookupVar "__nixPath"
|
||||||
case mres of
|
case mres of
|
||||||
Nothing -> error "impossible"
|
Nothing -> error "impossible"
|
||||||
Just x ->
|
Just x -> demand x $ fromValue >=> \(l :: [NValue t f m]) ->
|
||||||
force x $ fromValue >=> \(l :: [t]) -> findPathBy nixFilePath l name
|
findPathBy nixFilePath l name
|
||||||
where
|
where
|
||||||
nixFilePath :: MonadEffects t f m => FilePath -> m (Maybe FilePath)
|
nixFilePath :: MonadEffects t f m => FilePath -> m (Maybe FilePath)
|
||||||
nixFilePath path = do
|
nixFilePath path = do
|
||||||
|
@ -877,9 +886,9 @@ evalExprLoc expr = do
|
||||||
if tracing opts
|
if tracing opts
|
||||||
then join . (`runReaderT` (0 :: Int)) $ adi
|
then join . (`runReaderT` (0 :: Int)) $ adi
|
||||||
(addTracing phi)
|
(addTracing phi)
|
||||||
(raise (addStackFrames @t . addSourcePositions))
|
(raise (addStackFrames @(NValue t f m) . addSourcePositions))
|
||||||
expr
|
expr
|
||||||
else adi phi (addStackFrames @t . addSourcePositions) expr
|
else adi phi (addStackFrames @(NValue t f m) . addSourcePositions) expr
|
||||||
where
|
where
|
||||||
phi = Eval.eval . annotated . getCompose
|
phi = Eval.eval . annotated . getCompose
|
||||||
raise k f x = ReaderT $ \e -> k (\t -> runReaderT (f t) e) x
|
raise k f x = ReaderT $ \e -> k (\t -> runReaderT (f t) e) x
|
||||||
|
@ -890,7 +899,7 @@ fetchTarball v = v >>= \case
|
||||||
NVSet s _ -> case M.lookup "url" s of
|
NVSet s _ -> case M.lookup "url" s of
|
||||||
Nothing ->
|
Nothing ->
|
||||||
throwError $ ErrorCall "builtins.fetchTarball: Missing url attribute"
|
throwError $ ErrorCall "builtins.fetchTarball: Missing url attribute"
|
||||||
Just url -> force url $ go (M.lookup "sha256" s)
|
Just url -> demand url $ go (M.lookup "sha256" s)
|
||||||
v@NVStr{} -> go Nothing v
|
v@NVStr{} -> go Nothing v
|
||||||
v ->
|
v ->
|
||||||
throwError
|
throwError
|
||||||
|
@ -898,7 +907,7 @@ fetchTarball v = v >>= \case
|
||||||
$ "builtins.fetchTarball: Expected URI or set, got "
|
$ "builtins.fetchTarball: Expected URI or set, got "
|
||||||
++ show v
|
++ show v
|
||||||
where
|
where
|
||||||
go :: Maybe t -> NValue t f m -> m (NValue t f m)
|
go :: Maybe (NValue t f m) -> NValue t f m -> m (NValue t f m)
|
||||||
go msha = \case
|
go msha = \case
|
||||||
NVStr ns -> fetch (hackyStringIgnoreContext ns) msha
|
NVStr ns -> fetch (hackyStringIgnoreContext ns) msha
|
||||||
v ->
|
v ->
|
||||||
|
@ -919,10 +928,10 @@ fetchTarball v = v >>= \case
|
||||||
++ ext ++ "'"
|
++ ext ++ "'"
|
||||||
-}
|
-}
|
||||||
|
|
||||||
fetch :: Text -> Maybe t -> m (NValue t f m)
|
fetch :: Text -> Maybe (NValue t f m) -> m (NValue t f m)
|
||||||
fetch uri Nothing =
|
fetch uri Nothing =
|
||||||
nixInstantiateExpr $ "builtins.fetchTarball \"" ++ Text.unpack uri ++ "\""
|
nixInstantiateExpr $ "builtins.fetchTarball \"" ++ Text.unpack uri ++ "\""
|
||||||
fetch url (Just t) = force t $ fromValue >=> \nsSha ->
|
fetch url (Just t) = demand t $ fromValue >=> \nsSha ->
|
||||||
let sha = hackyStringIgnoreContext nsSha
|
let sha = hackyStringIgnoreContext nsSha
|
||||||
in nixInstantiateExpr
|
in nixInstantiateExpr
|
||||||
$ "builtins.fetchTarball { "
|
$ "builtins.fetchTarball { "
|
||||||
|
@ -940,15 +949,8 @@ nixInstantiateExpr
|
||||||
:: (MonadNix e t f m, MonadInstantiate m) => String -> m (NValue t f m)
|
:: (MonadNix e t f m, MonadInstantiate m) => String -> m (NValue t f m)
|
||||||
nixInstantiateExpr s = either throwError evalExprLoc =<< instantiateExpr s
|
nixInstantiateExpr s = either throwError evalExprLoc =<< instantiateExpr s
|
||||||
|
|
||||||
instance Monad m => Scoped t (Lazy t f m) where
|
instance Monad m => Scoped (NValue t f (Lazy t f m)) (Lazy t f m) where
|
||||||
currentScopes = currentScopesReader
|
currentScopes = currentScopesReader
|
||||||
clearScopes = clearScopesReader @(Lazy t f m) @t
|
clearScopes = clearScopesReader @(Lazy t f m) @(NValue t f (Lazy t f m))
|
||||||
pushScopes = pushScopesReader
|
pushScopes = pushScopesReader
|
||||||
lookupVar = lookupVarReader
|
lookupVar = lookupVarReader
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,21 +13,26 @@
|
||||||
module Nix.Normal where
|
module Nix.Normal where
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import Control.Monad.Free
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.Trans.Class
|
||||||
import Control.Monad.Trans.Reader
|
import Control.Monad.Trans.Reader
|
||||||
import Control.Monad.Trans.State
|
import Control.Monad.Trans.State
|
||||||
|
import Data.Fix
|
||||||
import Data.Set
|
import Data.Set
|
||||||
|
import Nix.Cited
|
||||||
import Nix.Frames
|
import Nix.Frames
|
||||||
import Nix.String
|
import Nix.String
|
||||||
import Nix.Thunk
|
import Nix.Thunk
|
||||||
import Nix.Value
|
import Nix.Value
|
||||||
|
import Nix.Utils
|
||||||
|
|
||||||
newtype NormalLoop t f m = NormalLoop (NValue t f m)
|
newtype NormalLoop t f m = NormalLoop (NValue t f m)
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
instance MonadDataErrorContext t f m => Exception (NormalLoop t f m)
|
instance MonadDataErrorContext t f m => Exception (NormalLoop t f m)
|
||||||
|
|
||||||
normalForm'
|
-- | Normalize the value as much as possible, leaving only detected cycles.
|
||||||
|
normalize
|
||||||
:: forall e t m f
|
:: forall e t m f
|
||||||
. ( Framed e m
|
. ( Framed e m
|
||||||
, MonadThunk t m (NValue t f m)
|
, MonadThunk t m (NValue t f m)
|
||||||
|
@ -36,8 +41,8 @@ normalForm'
|
||||||
)
|
)
|
||||||
=> (forall r . t -> (NValue t f m -> m r) -> m r)
|
=> (forall r . t -> (NValue t f m -> m r) -> m r)
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
-> m (NValueNF t f m)
|
-> m (NValue t f m)
|
||||||
normalForm' f = run . nValueToNFM run go
|
normalize f = run . iterNValueM run go (fmap Free . sequenceNValue' run)
|
||||||
where
|
where
|
||||||
start = 0 :: Int
|
start = 0 :: Int
|
||||||
table = mempty
|
table = mempty
|
||||||
|
@ -48,39 +53,54 @@ normalForm' f = run . nValueToNFM run go
|
||||||
go
|
go
|
||||||
:: t
|
:: t
|
||||||
-> ( NValue t f m
|
-> ( NValue t f m
|
||||||
-> ReaderT Int (StateT (Set (ThunkId m)) m) (NValueNF t f m)
|
-> ReaderT Int (StateT (Set (ThunkId m)) m) (NValue t f m)
|
||||||
)
|
)
|
||||||
-> ReaderT Int (StateT (Set (ThunkId m)) m) (NValueNF t f m)
|
-> ReaderT Int (StateT (Set (ThunkId m)) m) (NValue t f m)
|
||||||
go t k = do
|
go t k = do
|
||||||
b <- seen t
|
b <- seen t
|
||||||
if b
|
if b
|
||||||
then return $ pure t
|
then return $ Pure t
|
||||||
else do
|
else do
|
||||||
i <- ask
|
i <- ask
|
||||||
when (i > 2000)
|
when (i > 2000)
|
||||||
$ error "Exceeded maximum normalization depth of 2000 levels"
|
$ error "Exceeded maximum normalization depth of 2000 levels"
|
||||||
s <- lift get
|
lifted (lifted (f t)) $ local succ . k
|
||||||
(res, s') <- lift $ lift $ f t $ \v ->
|
|
||||||
(`runStateT` s) . (`runReaderT` i) $ local succ $ k v
|
|
||||||
lift $ put s'
|
|
||||||
return res
|
|
||||||
|
|
||||||
seen t = case thunkId t of
|
seen t = do
|
||||||
Just tid -> lift $ do
|
let tid = thunkId t
|
||||||
|
lift $ do
|
||||||
res <- gets (member tid)
|
res <- gets (member tid)
|
||||||
unless res $ modify (insert tid)
|
unless res $ modify (insert tid)
|
||||||
return res
|
return res
|
||||||
Nothing -> return False
|
|
||||||
|
stubCycles
|
||||||
|
:: forall t f m
|
||||||
|
. ( Applicative f
|
||||||
|
, Functor m
|
||||||
|
, HasCitations m (NValue t f m) t
|
||||||
|
, HasCitations1 m (NValue t f m) f
|
||||||
|
)
|
||||||
|
=> NValue t f m -> NValueNF t f m
|
||||||
|
stubCycles = freeToFix $ \t -> Fix
|
||||||
|
$ NValue
|
||||||
|
$ Prelude.foldr (addProvenance1 @m @(NValue t f m)) cyc
|
||||||
|
$ reverse
|
||||||
|
$ citations @m @(NValue t f m) t
|
||||||
|
where
|
||||||
|
Fix (NValue cyc) =
|
||||||
|
nvStrNF (principledMakeNixStringWithoutContext "<CYCLE>")
|
||||||
|
|
||||||
normalForm
|
normalForm
|
||||||
:: ( Framed e m
|
:: ( Framed e m
|
||||||
, MonadThunk t m (NValue t f m)
|
, MonadThunk t m (NValue t f m)
|
||||||
, MonadDataErrorContext t f m
|
, MonadDataErrorContext t f m
|
||||||
|
, HasCitations m (NValue t f m) t
|
||||||
|
, HasCitations1 m (NValue t f m) f
|
||||||
, Ord (ThunkId m)
|
, Ord (ThunkId m)
|
||||||
)
|
)
|
||||||
=> NValue t f m
|
=> NValue t f m
|
||||||
-> m (NValueNF t f m)
|
-> m (NValueNF t f m)
|
||||||
normalForm = normalForm' force
|
normalForm = fmap stubCycles . normalize force
|
||||||
|
|
||||||
normalForm_
|
normalForm_
|
||||||
:: ( Framed e m
|
:: ( Framed e m
|
||||||
|
@ -90,19 +110,13 @@ normalForm_
|
||||||
)
|
)
|
||||||
=> NValue t f m
|
=> NValue t f m
|
||||||
-> m ()
|
-> m ()
|
||||||
normalForm_ = void <$> normalForm' forceEff
|
normalForm_ = void <$> normalize forceEff
|
||||||
|
|
||||||
removeEffects
|
removeEffects
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
|
||||||
=> NValue t f m
|
|
||||||
-> NValueNF t f m
|
|
||||||
removeEffects = nValueToNF (flip query opaque)
|
|
||||||
|
|
||||||
removeEffectsM
|
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> NValue t f m
|
=> NValue t f m
|
||||||
-> m (NValueNF t f m)
|
-> m (NValueNF t f m)
|
||||||
removeEffectsM = nValueToNFM id (flip queryM (pure opaque))
|
removeEffects = nValueToNFM id (flip queryM (pure opaque))
|
||||||
|
|
||||||
opaque
|
opaque
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m) => NValueNF t f m
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m) => NValueNF t f m
|
||||||
|
@ -112,4 +126,4 @@ dethunk
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> t
|
=> t
|
||||||
-> m (NValueNF t f m)
|
-> m (NValueNF t f m)
|
||||||
dethunk t = queryM t (pure opaque) removeEffectsM
|
dethunk t = queryM t (pure opaque) removeEffects
|
||||||
|
|
|
@ -18,6 +18,7 @@ module Nix.Pretty where
|
||||||
|
|
||||||
import Control.Applicative ( (<|>) )
|
import Control.Applicative ( (<|>) )
|
||||||
import Control.Comonad
|
import Control.Comonad
|
||||||
|
import Control.Monad.Free
|
||||||
import Data.Fix
|
import Data.Fix
|
||||||
import Data.HashMap.Lazy ( toList )
|
import Data.HashMap.Lazy ( toList )
|
||||||
import qualified Data.HashMap.Lazy as M
|
import qualified Data.HashMap.Lazy as M
|
||||||
|
@ -192,14 +193,25 @@ prettyAtom atom = simpleExpr $ pretty $ unpack $ atomText atom
|
||||||
prettyNix :: NExpr -> Doc ann
|
prettyNix :: NExpr -> Doc ann
|
||||||
prettyNix = withoutParens . cata exprFNixDoc
|
prettyNix = withoutParens . cata exprFNixDoc
|
||||||
|
|
||||||
instance HasCitations1 t m v f
|
instance HasCitations1 m v f
|
||||||
=> HasCitations t m v (NValue' t f m a) where
|
=> HasCitations m v (NValue' t f m a) where
|
||||||
citations (NValue f) = citations1 f
|
citations (NValue f) = citations1 f
|
||||||
addProvenance x (NValue f) = NValue (addProvenance1 x f)
|
addProvenance x (NValue f) = NValue (addProvenance1 x f)
|
||||||
|
|
||||||
|
instance (HasCitations1 m v f, HasCitations m v t)
|
||||||
|
=> HasCitations m v (NValue t f m) where
|
||||||
|
citations (Pure t) = citations t
|
||||||
|
citations (Free v) = citations v
|
||||||
|
addProvenance x (Pure t) = Pure (addProvenance x t)
|
||||||
|
addProvenance x (Free v) = Free (addProvenance x v)
|
||||||
|
|
||||||
|
instance HasCitations1 m v f => HasCitations m v (NValueNF t f m) where
|
||||||
|
citations (Fix v) = citations v
|
||||||
|
addProvenance x (Fix v) = Fix (addProvenance x v)
|
||||||
|
|
||||||
prettyOriginExpr
|
prettyOriginExpr
|
||||||
:: forall t f m ann
|
:: forall t f m ann
|
||||||
. HasCitations1 t m (NValue t f m) f
|
. HasCitations1 m (NValue t f m) f
|
||||||
=> NExprLocF (Maybe (NValue t f m))
|
=> NExprLocF (Maybe (NValue t f m))
|
||||||
-> Doc ann
|
-> Doc ann
|
||||||
prettyOriginExpr = withoutParens . go
|
prettyOriginExpr = withoutParens . go
|
||||||
|
@ -208,7 +220,7 @@ prettyOriginExpr = withoutParens . go
|
||||||
|
|
||||||
render :: Maybe (NValue t f m) -> NixDoc ann
|
render :: Maybe (NValue t f m) -> NixDoc ann
|
||||||
render Nothing = simpleExpr $ "_"
|
render Nothing = simpleExpr $ "_"
|
||||||
render (Just (reverse . citations @t @m -> p:_)) = go (_originExpr p)
|
render (Just (Free (reverse . citations @m -> p:_))) = go (_originExpr p)
|
||||||
render _ = simpleExpr "?"
|
render _ = simpleExpr "?"
|
||||||
-- render (Just (NValue (citations -> ps))) =
|
-- render (Just (NValue (citations -> ps))) =
|
||||||
-- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . withoutParens
|
-- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . withoutParens
|
||||||
|
@ -314,21 +326,19 @@ exprFNixDoc = \case
|
||||||
where recPrefix = "rec" <> space
|
where recPrefix = "rec" <> space
|
||||||
|
|
||||||
valueToExpr :: forall t f m . MonadDataContext f m => NValueNF t f m -> NExpr
|
valueToExpr :: forall t f m . MonadDataContext f m => NValueNF t f m -> NExpr
|
||||||
valueToExpr = iterNValueNF
|
valueToExpr = iterNValueNF phi
|
||||||
(const (mkStr (principledMakeNixStringWithoutContext "<CYCLE>")))
|
|
||||||
phi
|
|
||||||
where
|
where
|
||||||
phi :: NValue' t f m NExpr -> NExpr
|
phi :: NValue' t f m NExpr -> NExpr
|
||||||
phi (NVConstant a ) = Fix $ NConstant a
|
phi (NVConstant' a ) = Fix $ NConstant a
|
||||||
phi (NVStr ns) = mkStr ns
|
phi (NVStr' ns) = mkStr ns
|
||||||
phi (NVList l ) = Fix $ NList l
|
phi (NVList' l ) = Fix $ NList l
|
||||||
phi (NVSet s p ) = Fix $ NSet
|
phi (NVSet' s p ) = Fix $ NSet
|
||||||
[ NamedVar (StaticKey k :| []) v (fromMaybe nullPos (M.lookup k p))
|
[ NamedVar (StaticKey k :| []) v (fromMaybe nullPos (M.lookup k p))
|
||||||
| (k, v) <- toList s
|
| (k, v) <- toList s
|
||||||
]
|
]
|
||||||
phi (NVClosure _ _ ) = Fix . NSym . pack $ "<closure>"
|
phi (NVClosure' _ _ ) = Fix . NSym . pack $ "<closure>"
|
||||||
phi (NVPath p ) = Fix $ NLiteralPath p
|
phi (NVPath' p ) = Fix $ NLiteralPath p
|
||||||
phi (NVBuiltin name _) = Fix . NSym . pack $ "builtins." ++ name
|
phi (NVBuiltin' name _) = Fix . NSym . pack $ "builtins." ++ name
|
||||||
phi _ = error "Pattern synonyms foil completeness check"
|
phi _ = error "Pattern synonyms foil completeness check"
|
||||||
|
|
||||||
mkStr ns = Fix $ NStr $ DoubleQuoted [Plain (hackyStringIgnoreContext ns)]
|
mkStr ns = Fix $ NStr $ DoubleQuoted [Plain (hackyStringIgnoreContext ns)]
|
||||||
|
@ -337,13 +347,13 @@ prettyNValueNF :: MonadDataContext f m => NValueNF t f m -> Doc ann
|
||||||
prettyNValueNF = prettyNix . valueToExpr
|
prettyNValueNF = prettyNix . valueToExpr
|
||||||
|
|
||||||
printNix :: forall t f m . MonadDataContext f m => NValueNF t f m -> String
|
printNix :: forall t f m . MonadDataContext f m => NValueNF t f m -> String
|
||||||
printNix = iterNValueNF (const "<CYCLE>") phi
|
printNix = iterNValueNF phi
|
||||||
where
|
where
|
||||||
phi :: NValue' t f m String -> String
|
phi :: NValue' t f m String -> String
|
||||||
phi (NVConstant a ) = unpack $ atomText a
|
phi (NVConstant' a ) = unpack $ atomText a
|
||||||
phi (NVStr ns) = show $ hackyStringIgnoreContext ns
|
phi (NVStr' ns) = show $ hackyStringIgnoreContext ns
|
||||||
phi (NVList l ) = "[ " ++ unwords l ++ " ]"
|
phi (NVList' l ) = "[ " ++ unwords l ++ " ]"
|
||||||
phi (NVSet s _) =
|
phi (NVSet' s _) =
|
||||||
"{ "
|
"{ "
|
||||||
++ concat
|
++ concat
|
||||||
[ check (unpack k) ++ " = " ++ v ++ "; "
|
[ check (unpack k) ++ " = " ++ v ++ "; "
|
||||||
|
@ -357,27 +367,28 @@ printNix = iterNValueNF (const "<CYCLE>") phi
|
||||||
<|> (fmap (surround . show) (readMaybe v :: Maybe Float))
|
<|> (fmap (surround . show) (readMaybe v :: Maybe Float))
|
||||||
)
|
)
|
||||||
where surround s = "\"" ++ s ++ "\""
|
where surround s = "\"" ++ s ++ "\""
|
||||||
phi NVClosure{} = "<<lambda>>"
|
phi NVClosure'{} = "<<lambda>>"
|
||||||
phi (NVPath fp ) = fp
|
phi (NVPath' fp ) = fp
|
||||||
phi (NVBuiltin name _) = "<<builtin " ++ name ++ ">>"
|
phi (NVBuiltin' name _) = "<<builtin " ++ name ++ ">>"
|
||||||
phi _ = error "Pattern synonyms foil completeness check"
|
phi _ = error "Pattern synonyms foil completeness check"
|
||||||
|
|
||||||
prettyNValue
|
prettyNValue
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> NValue t f m
|
=> NValue t f m
|
||||||
-> m (Doc ann)
|
-> m (Doc ann)
|
||||||
prettyNValue = fmap prettyNValueNF . removeEffectsM
|
prettyNValue = fmap prettyNValueNF . removeEffects
|
||||||
|
|
||||||
prettyNValueProv
|
prettyNValueProv
|
||||||
:: forall t f m ann
|
:: forall t f m ann
|
||||||
. ( HasCitations1 t m (NValue t f m) f
|
. ( HasCitations m (NValue t f m) t
|
||||||
|
, HasCitations1 m (NValue t f m) f
|
||||||
, MonadThunk t m (NValue t f m)
|
, MonadThunk t m (NValue t f m)
|
||||||
, MonadDataContext f m
|
, MonadDataContext f m
|
||||||
)
|
)
|
||||||
=> NValue t f m
|
=> NValue t f m
|
||||||
-> m (Doc ann)
|
-> m (Doc ann)
|
||||||
prettyNValueProv v@(NValue nv) = do
|
prettyNValueProv v = do
|
||||||
let ps = citations1 @t @m @(NValue t f m) @f nv
|
let ps = citations @m @(NValue t f m) v
|
||||||
case ps of
|
case ps of
|
||||||
[] -> prettyNValue v
|
[] -> prettyNValue v
|
||||||
ps -> do
|
ps -> do
|
||||||
|
@ -394,15 +405,15 @@ prettyNValueProv v@(NValue nv) = do
|
||||||
|
|
||||||
prettyNThunk
|
prettyNThunk
|
||||||
:: forall t f m ann
|
:: forall t f m ann
|
||||||
. ( HasCitations t m (NValue t f m) t
|
. ( HasCitations m (NValue t f m) t
|
||||||
, HasCitations1 t m (NValue t f m) f
|
, HasCitations1 m (NValue t f m) f
|
||||||
, MonadThunk t m (NValue t f m)
|
, MonadThunk t m (NValue t f m)
|
||||||
, MonadDataContext f m
|
, MonadDataContext f m
|
||||||
)
|
)
|
||||||
=> t
|
=> t
|
||||||
-> m (Doc ann)
|
-> m (Doc ann)
|
||||||
prettyNThunk t = do
|
prettyNThunk t = do
|
||||||
let ps = citations @t @m @(NValue t f m) @t t
|
let ps = citations @m @(NValue t f m) @t t
|
||||||
v' <- prettyNValueNF <$> dethunk t
|
v' <- prettyNValueNF <$> dethunk t
|
||||||
pure
|
pure
|
||||||
$ fillSep
|
$ fillSep
|
||||||
|
|
|
@ -20,64 +20,64 @@ import Data.Text ( Text )
|
||||||
import Lens.Family2
|
import Lens.Family2
|
||||||
import Nix.Utils
|
import Nix.Utils
|
||||||
|
|
||||||
newtype Scope t = Scope { getScope :: AttrSet t }
|
newtype Scope a = Scope { getScope :: AttrSet a }
|
||||||
deriving (Functor, Foldable, Traversable, Eq)
|
deriving (Functor, Foldable, Traversable, Eq)
|
||||||
|
|
||||||
instance Show (Scope t) where
|
instance Show (Scope a) where
|
||||||
show (Scope m) = show (M.keys m)
|
show (Scope m) = show (M.keys m)
|
||||||
|
|
||||||
newScope :: AttrSet t -> Scope t
|
newScope :: AttrSet a -> Scope a
|
||||||
newScope = Scope
|
newScope = Scope
|
||||||
|
|
||||||
scopeLookup :: Text -> [Scope t] -> Maybe t
|
scopeLookup :: Text -> [Scope a] -> Maybe a
|
||||||
scopeLookup key = foldr go Nothing
|
scopeLookup key = foldr go Nothing
|
||||||
where go (Scope m) rest = M.lookup key m <|> rest
|
where go (Scope m) rest = M.lookup key m <|> rest
|
||||||
|
|
||||||
data Scopes m t = Scopes
|
data Scopes m a = Scopes
|
||||||
{ lexicalScopes :: [Scope t]
|
{ lexicalScopes :: [Scope a]
|
||||||
, dynamicScopes :: [m (Scope t)]
|
, dynamicScopes :: [m (Scope a)]
|
||||||
}
|
}
|
||||||
|
|
||||||
instance Show (Scopes m t) where
|
instance Show (Scopes m a) where
|
||||||
show (Scopes m t) =
|
show (Scopes m a) =
|
||||||
"Scopes: " ++ show m ++ ", and " ++ show (length t) ++ " with-scopes"
|
"Scopes: " ++ show m ++ ", and " ++ show (length a) ++ " with-scopes"
|
||||||
|
|
||||||
instance Semigroup (Scopes m t) where
|
instance Semigroup (Scopes m a) where
|
||||||
Scopes ls lw <> Scopes rs rw = Scopes (ls <> rs) (lw <> rw)
|
Scopes ls lw <> Scopes rs rw = Scopes (ls <> rs) (lw <> rw)
|
||||||
|
|
||||||
instance Monoid (Scopes m t) where
|
instance Monoid (Scopes m a) where
|
||||||
mempty = emptyScopes
|
mempty = emptyScopes
|
||||||
mappend = (<>)
|
mappend = (<>)
|
||||||
|
|
||||||
emptyScopes :: forall m t . Scopes m t
|
emptyScopes :: forall m a . Scopes m a
|
||||||
emptyScopes = Scopes [] []
|
emptyScopes = Scopes [] []
|
||||||
|
|
||||||
class Scoped t m | m -> t where
|
class Scoped a m | m -> a where
|
||||||
currentScopes :: m (Scopes m t)
|
currentScopes :: m (Scopes m a)
|
||||||
clearScopes :: m a -> m a
|
clearScopes :: m r -> m r
|
||||||
pushScopes :: Scopes m t -> m a -> m a
|
pushScopes :: Scopes m a -> m r -> m r
|
||||||
lookupVar :: Text -> m (Maybe t)
|
lookupVar :: Text -> m (Maybe a)
|
||||||
|
|
||||||
currentScopesReader
|
currentScopesReader
|
||||||
:: forall m t e . (MonadReader e m, Has e (Scopes m t)) => m (Scopes m t)
|
:: forall m a e . (MonadReader e m, Has e (Scopes m a)) => m (Scopes m a)
|
||||||
currentScopesReader = asks (view hasLens)
|
currentScopesReader = asks (view hasLens)
|
||||||
|
|
||||||
clearScopesReader
|
clearScopesReader
|
||||||
:: forall m t e a . (MonadReader e m, Has e (Scopes m t)) => m a -> m a
|
:: forall m a e r . (MonadReader e m, Has e (Scopes m a)) => m r -> m r
|
||||||
clearScopesReader = local (set hasLens (emptyScopes @m @t))
|
clearScopesReader = local (set hasLens (emptyScopes @m @a))
|
||||||
|
|
||||||
pushScope :: Scoped t m => AttrSet t -> m a -> m a
|
pushScope :: Scoped a m => AttrSet a -> m r -> m r
|
||||||
pushScope s = pushScopes (Scopes [Scope s] [])
|
pushScope s = pushScopes (Scopes [Scope s] [])
|
||||||
|
|
||||||
pushWeakScope :: (Functor m, Scoped t m) => m (AttrSet t) -> m a -> m a
|
pushWeakScope :: (Functor m, Scoped a m) => m (AttrSet a) -> m r -> m r
|
||||||
pushWeakScope s = pushScopes (Scopes [] [Scope <$> s])
|
pushWeakScope s = pushScopes (Scopes [] [Scope <$> s])
|
||||||
|
|
||||||
pushScopesReader
|
pushScopesReader
|
||||||
:: (MonadReader e m, Has e (Scopes m t)) => Scopes m t -> m a -> m a
|
:: (MonadReader e m, Has e (Scopes m a)) => Scopes m a -> m r -> m r
|
||||||
pushScopesReader s = local (over hasLens (s <>))
|
pushScopesReader s = local (over hasLens (s <>))
|
||||||
|
|
||||||
lookupVarReader
|
lookupVarReader
|
||||||
:: forall m t e . (MonadReader e m, Has e (Scopes m t)) => Text -> m (Maybe t)
|
:: forall m a e . (MonadReader e m, Has e (Scopes m a)) => Text -> m (Maybe a)
|
||||||
lookupVarReader k = do
|
lookupVarReader k = do
|
||||||
mres <- asks (scopeLookup k . lexicalScopes @m . view hasLens)
|
mres <- asks (scopeLookup k . lexicalScopes @m . view hasLens)
|
||||||
case mres of
|
case mres of
|
||||||
|
@ -94,5 +94,5 @@ lookupVarReader k = do
|
||||||
(return Nothing)
|
(return Nothing)
|
||||||
ws
|
ws
|
||||||
|
|
||||||
withScopes :: Scoped t m => Scopes m t -> m a -> m a
|
withScopes :: Scoped a m => Scopes m a -> m r -> m r
|
||||||
withScopes scope = clearScopes . pushScopes scope
|
withScopes scope = clearScopes . pushScopes scope
|
||||||
|
|
|
@ -29,18 +29,15 @@ class ( Monad m
|
||||||
=> m (ThunkId m)
|
=> m (ThunkId m)
|
||||||
freshId = lift freshId
|
freshId = lift freshId
|
||||||
|
|
||||||
class MonadThunkId m => MonadThunk t m v | t -> m, t -> v where
|
class MonadThunkId m => MonadThunk t m a | t -> m, t -> a where
|
||||||
thunk :: m v -> m t
|
thunk :: m a -> m t
|
||||||
-- | Return an identifier for the thunk unless it is a pure value (i.e.,
|
-- | Return an identifier for the thunk unless it is a pure value (i.e.,
|
||||||
-- strictly an encapsulation of some 'v' without any additional
|
-- strictly an encapsulation of some 'a' without any additional
|
||||||
-- structure). For pure values represented as thunks, returns Nothing.
|
-- structure). For pure values represented as thunks, returns Nothing.
|
||||||
thunkId :: t -> Maybe (ThunkId m)
|
thunkId :: t -> ThunkId m
|
||||||
query :: t -> r -> (v -> r) -> r
|
queryM :: t -> m r -> (a -> m r) -> m r
|
||||||
queryM :: t -> m r -> (v -> m r) -> m r
|
force :: t -> (a -> m r) -> m r
|
||||||
force :: t -> (v -> m r) -> m r
|
forceEff :: t -> (a -> m r) -> m r
|
||||||
forceEff :: t -> (v -> m r) -> m r
|
|
||||||
wrapValue :: v -> t
|
|
||||||
getValue :: t -> Maybe v
|
|
||||||
|
|
||||||
newtype ThunkLoop = ThunkLoop String -- contains rendering of ThunkId
|
newtype ThunkLoop = ThunkLoop String -- contains rendering of ThunkId
|
||||||
deriving Typeable
|
deriving Typeable
|
||||||
|
|
|
@ -27,16 +27,12 @@ data Deferred m v = Deferred (m v) | Computed v
|
||||||
|
|
||||||
-- | The type of very basic thunks
|
-- | The type of very basic thunks
|
||||||
data NThunkF m v
|
data NThunkF m v
|
||||||
= Value v
|
= Thunk (ThunkId m) (Var m Bool) (Var m (Deferred m v))
|
||||||
| Thunk (ThunkId m) (Var m Bool) (Var m (Deferred m v))
|
|
||||||
|
|
||||||
instance (Eq v, Eq (ThunkId m)) => Eq (NThunkF m v) where
|
instance (Eq v, Eq (ThunkId m)) => Eq (NThunkF m v) where
|
||||||
Value x == Value y = x == y
|
|
||||||
Thunk x _ _ == Thunk y _ _ = x == y
|
Thunk x _ _ == Thunk y _ _ = x == y
|
||||||
_ == _ = False -- jww (2019-03-16): not accurate...
|
|
||||||
|
|
||||||
instance Show v => Show (NThunkF m v) where
|
instance Show v => Show (NThunkF m v) where
|
||||||
show (Value v ) = show v
|
|
||||||
show (Thunk _ _ _) = "<thunk>"
|
show (Thunk _ _ _) = "<thunk>"
|
||||||
|
|
||||||
type MonadBasicThunk m = (MonadThunkId m, MonadVar m)
|
type MonadBasicThunk m = (MonadThunkId m, MonadVar m)
|
||||||
|
@ -44,34 +40,17 @@ type MonadBasicThunk m = (MonadThunkId m, MonadVar m)
|
||||||
instance (MonadBasicThunk m, MonadCatch m)
|
instance (MonadBasicThunk m, MonadCatch m)
|
||||||
=> MonadThunk (NThunkF m v) m v where
|
=> MonadThunk (NThunkF m v) m v where
|
||||||
thunk = buildThunk
|
thunk = buildThunk
|
||||||
thunkId = \case
|
thunkId (Thunk n _ _) = n
|
||||||
Value _ -> Nothing
|
|
||||||
Thunk n _ _ -> Just n
|
|
||||||
query = queryValue
|
|
||||||
queryM = queryThunk
|
queryM = queryThunk
|
||||||
force = forceThunk
|
force = forceThunk
|
||||||
forceEff = forceEffects
|
forceEff = forceEffects
|
||||||
wrapValue = valueRef
|
|
||||||
getValue = thunkValue
|
|
||||||
|
|
||||||
valueRef :: v -> NThunkF m v
|
|
||||||
valueRef = Value
|
|
||||||
|
|
||||||
thunkValue :: NThunkF m v -> Maybe v
|
|
||||||
thunkValue (Value v) = Just v
|
|
||||||
thunkValue _ = Nothing
|
|
||||||
|
|
||||||
buildThunk :: MonadBasicThunk m => m v -> m (NThunkF m v)
|
buildThunk :: MonadBasicThunk m => m v -> m (NThunkF m v)
|
||||||
buildThunk action = do
|
buildThunk action = do
|
||||||
freshThunkId <- freshId
|
freshThunkId <- freshId
|
||||||
Thunk freshThunkId <$> newVar False <*> newVar (Deferred action)
|
Thunk freshThunkId <$> newVar False <*> newVar (Deferred action)
|
||||||
|
|
||||||
queryValue :: MonadVar m => NThunkF m v -> a -> (v -> a) -> a
|
|
||||||
queryValue (Value v) _ k = k v
|
|
||||||
queryValue _ n _ = n
|
|
||||||
|
|
||||||
queryThunk :: MonadVar m => NThunkF m v -> m a -> (v -> m a) -> m a
|
queryThunk :: MonadVar m => NThunkF m v -> m a -> (v -> m a) -> m a
|
||||||
queryThunk (Value v ) _ k = k v
|
|
||||||
queryThunk (Thunk _ active ref) n k = do
|
queryThunk (Thunk _ active ref) n k = do
|
||||||
nowActive <- atomicModifyVar active (True, )
|
nowActive <- atomicModifyVar active (True, )
|
||||||
if nowActive
|
if nowActive
|
||||||
|
@ -90,7 +69,6 @@ forceThunk
|
||||||
=> NThunkF m v
|
=> NThunkF m v
|
||||||
-> (v -> m a)
|
-> (v -> m a)
|
||||||
-> m a
|
-> m a
|
||||||
forceThunk (Value v ) k = k v
|
|
||||||
forceThunk (Thunk n active ref) k = do
|
forceThunk (Thunk n active ref) k = do
|
||||||
eres <- readVar ref
|
eres <- readVar ref
|
||||||
case eres of
|
case eres of
|
||||||
|
@ -109,7 +87,6 @@ forceThunk (Thunk n active ref) k = do
|
||||||
k v
|
k v
|
||||||
|
|
||||||
forceEffects :: MonadVar m => NThunkF m v -> (v -> m r) -> m r
|
forceEffects :: MonadVar m => NThunkF m v -> (v -> m r) -> m r
|
||||||
forceEffects (Value v ) k = k v
|
|
||||||
forceEffects (Thunk _ active ref) k = do
|
forceEffects (Thunk _ active ref) k = do
|
||||||
nowActive <- atomicModifyVar active (True, )
|
nowActive <- atomicModifyVar active (True, )
|
||||||
if nowActive
|
if nowActive
|
||||||
|
|
|
@ -15,6 +15,8 @@ module Nix.Utils (module Nix.Utils, module X) where
|
||||||
import Control.Arrow ( (&&&) )
|
import Control.Arrow ( (&&&) )
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Control.Monad.Fix
|
import Control.Monad.Fix
|
||||||
|
import Control.Monad.Free
|
||||||
|
import Control.Monad.Trans.Control ( MonadTransControl(..) )
|
||||||
import qualified Data.Aeson as A
|
import qualified Data.Aeson as A
|
||||||
import qualified Data.Aeson.Encoding as A
|
import qualified Data.Aeson.Encoding as A
|
||||||
import Data.Fix
|
import Data.Fix
|
||||||
|
@ -28,6 +30,7 @@ import Data.Monoid ( Endo
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import qualified Data.Text as Text
|
import qualified Data.Text as Text
|
||||||
import qualified Data.Vector as V
|
import qualified Data.Vector as V
|
||||||
|
import Data.Void
|
||||||
import Lens.Family2 as X
|
import Lens.Family2 as X
|
||||||
import Lens.Family2.Stock ( _1
|
import Lens.Family2.Stock ( _1
|
||||||
, _2
|
, _2
|
||||||
|
@ -90,6 +93,25 @@ cataPM f x = f x <=< traverse (cataPM f) . unFix $ x
|
||||||
transport :: Functor g => (forall x . f x -> g x) -> Fix f -> Fix g
|
transport :: Functor g => (forall x . f x -> g x) -> Fix f -> Fix g
|
||||||
transport f (Fix x) = Fix $ fmap (transport f) (f x)
|
transport f (Fix x) = Fix $ fmap (transport f) (f x)
|
||||||
|
|
||||||
|
lifted
|
||||||
|
:: ( MonadTransControl u
|
||||||
|
, Monad (u m)
|
||||||
|
, Monad m
|
||||||
|
)
|
||||||
|
=> ((a -> m (StT u b)) -> m (StT u b)) -> (a -> u m b) -> u m b
|
||||||
|
lifted f k = liftWith (\run -> f (run . k)) >>= restoreT . return
|
||||||
|
|
||||||
|
freeToFix :: Functor f => (a -> Fix f) -> Free f a -> Fix f
|
||||||
|
freeToFix f = go
|
||||||
|
where
|
||||||
|
go (Pure a) = f a
|
||||||
|
go (Free v) = Fix (fmap go v)
|
||||||
|
|
||||||
|
fixToFree :: Functor f => Fix f -> Free f Void
|
||||||
|
fixToFree = Free . go
|
||||||
|
where
|
||||||
|
go (Fix f) = fmap (Free . go) f
|
||||||
|
|
||||||
-- | adi is Abstracting Definitional Interpreters:
|
-- | adi is Abstracting Definitional Interpreters:
|
||||||
--
|
--
|
||||||
-- https://arxiv.org/abs/1707.04755
|
-- https://arxiv.org/abs/1707.04755
|
||||||
|
|
303
src/Nix/Value.hs
303
src/Nix/Value.hs
|
@ -36,10 +36,12 @@ import Control.Monad
|
||||||
import Control.Monad.Free
|
import Control.Monad.Free
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.Trans.Class
|
||||||
import qualified Data.Aeson as A
|
import qualified Data.Aeson as A
|
||||||
|
import Data.Fix
|
||||||
import Data.Functor.Classes
|
import Data.Functor.Classes
|
||||||
import Data.HashMap.Lazy ( HashMap )
|
import Data.HashMap.Lazy ( HashMap )
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Typeable ( Typeable )
|
import Data.Typeable ( Typeable )
|
||||||
|
import Data.Void
|
||||||
import GHC.Generics
|
import GHC.Generics
|
||||||
import Lens.Family2
|
import Lens.Family2
|
||||||
import Lens.Family2.Stock
|
import Lens.Family2.Stock
|
||||||
|
@ -62,7 +64,7 @@ data NValueF p m r
|
||||||
| NVPathF FilePath
|
| NVPathF FilePath
|
||||||
| NVListF [r]
|
| NVListF [r]
|
||||||
| NVSetF (AttrSet r) (AttrSet SourcePos)
|
| NVSetF (AttrSet r) (AttrSet SourcePos)
|
||||||
| NVClosureF (Params ()) (m p -> m r)
|
| NVClosureF (Params ()) (p -> m r)
|
||||||
-- ^ A function is a closed set of parameters representing the "call
|
-- ^ A function is a closed set of parameters representing the "call
|
||||||
-- signature", used at application time to check the type of arguments
|
-- signature", used at application time to check the type of arguments
|
||||||
-- passed to the function. Since it supports default values which may
|
-- passed to the function. Since it supports default values which may
|
||||||
|
@ -74,7 +76,7 @@ data NValueF p m r
|
||||||
-- Note that 'm r' is being used here because effectively a function
|
-- Note that 'm r' is being used here because effectively a function
|
||||||
-- and its set of default arguments is "never fully evaluated". This
|
-- and its set of default arguments is "never fully evaluated". This
|
||||||
-- enforces in the type that it must be re-evaluated for each call.
|
-- enforces in the type that it must be re-evaluated for each call.
|
||||||
| NVBuiltinF String (m p -> m r)
|
| NVBuiltinF String (p -> m r)
|
||||||
-- ^ A builtin function is itself already in normal form. Also, it may
|
-- ^ 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
|
-- or may not choose to evaluate its argument in the production of a
|
||||||
-- result.
|
-- result.
|
||||||
|
@ -92,6 +94,20 @@ instance Foldable (NValueF p m) where
|
||||||
NVClosureF _ _ -> mempty
|
NVClosureF _ _ -> mempty
|
||||||
NVBuiltinF _ _ -> mempty
|
NVBuiltinF _ _ -> mempty
|
||||||
|
|
||||||
|
instance Show r => Show (NValueF p m r) where
|
||||||
|
showsPrec = flip go where
|
||||||
|
go (NVConstantF atom ) = showsCon1 "NVConstant" atom
|
||||||
|
go (NVStrF ns ) = showsCon1 "NVStr" (hackyStringIgnoreContext ns)
|
||||||
|
go (NVListF lst ) = showsCon1 "NVList" lst
|
||||||
|
go (NVSetF attrs _) = showsCon1 "NVSet" attrs
|
||||||
|
go (NVClosureF p _) = showsCon1 "NVClosure" p
|
||||||
|
go (NVPathF p ) = showsCon1 "NVPath" p
|
||||||
|
go (NVBuiltinF name _ ) = showsCon1 "NVBuiltin" name
|
||||||
|
|
||||||
|
showsCon1 :: Show a => String -> a -> Int -> String -> String
|
||||||
|
showsCon1 con a d =
|
||||||
|
showParen (d > 10) $ showString (con ++ " ") . showsPrec 11 a
|
||||||
|
|
||||||
lmapNValueF :: Functor m => (b -> a) -> NValueF a m r -> NValueF b m r
|
lmapNValueF :: Functor m => (b -> a) -> NValueF a m r -> NValueF b m r
|
||||||
lmapNValueF f = \case
|
lmapNValueF f = \case
|
||||||
NVConstantF a -> NVConstantF a
|
NVConstantF a -> NVConstantF a
|
||||||
|
@ -99,22 +115,21 @@ lmapNValueF f = \case
|
||||||
NVPathF p -> NVPathF p
|
NVPathF p -> NVPathF p
|
||||||
NVListF l -> NVListF l
|
NVListF l -> NVListF l
|
||||||
NVSetF s p -> NVSetF s p
|
NVSetF s p -> NVSetF s p
|
||||||
NVClosureF p g -> NVClosureF p (g . fmap f)
|
NVClosureF p g -> NVClosureF p (g . f)
|
||||||
NVBuiltinF s g -> NVBuiltinF s (g . fmap f)
|
NVBuiltinF s g -> NVBuiltinF s (g . f)
|
||||||
|
|
||||||
hoistNValueF
|
hoistNValueF
|
||||||
:: (forall x . n x -> m x)
|
:: (forall x . m x -> n x)
|
||||||
-> (forall x . m x -> n x)
|
|
||||||
-> NValueF p m a
|
-> NValueF p m a
|
||||||
-> NValueF p n a
|
-> NValueF p n a
|
||||||
hoistNValueF run lft = \case
|
hoistNValueF lft = \case
|
||||||
NVConstantF a -> NVConstantF a
|
NVConstantF a -> NVConstantF a
|
||||||
NVStrF s -> NVStrF s
|
NVStrF s -> NVStrF s
|
||||||
NVPathF p -> NVPathF p
|
NVPathF p -> NVPathF p
|
||||||
NVListF l -> NVListF l
|
NVListF l -> NVListF l
|
||||||
NVSetF s p -> NVSetF s p
|
NVSetF s p -> NVSetF s p
|
||||||
NVClosureF p g -> NVClosureF p (lft . g . run)
|
NVClosureF p g -> NVClosureF p (lft . g)
|
||||||
NVBuiltinF s g -> NVBuiltinF s (lft . g . run)
|
NVBuiltinF s g -> NVBuiltinF s (lft . g)
|
||||||
|
|
||||||
sequenceNValueF
|
sequenceNValueF
|
||||||
:: (Functor n, Monad m, Applicative n)
|
:: (Functor n, Monad m, Applicative n)
|
||||||
|
@ -147,17 +162,16 @@ bindNValueF transform f = \case
|
||||||
|
|
||||||
liftNValueF
|
liftNValueF
|
||||||
:: (MonadTrans u, Monad m)
|
:: (MonadTrans u, Monad m)
|
||||||
=> (forall x . u m x -> m x)
|
=> NValueF p m a
|
||||||
-> NValueF p m a
|
|
||||||
-> NValueF p (u m) a
|
-> NValueF p (u m) a
|
||||||
liftNValueF run = hoistNValueF run lift
|
liftNValueF = hoistNValueF lift
|
||||||
|
|
||||||
unliftNValueF
|
unliftNValueF
|
||||||
:: (MonadTrans u, Monad m)
|
:: (MonadTrans u, Monad m)
|
||||||
=> (forall x . u m x -> m x)
|
=> (forall x . u m x -> m x)
|
||||||
-> NValueF p (u m) a
|
-> NValueF p (u m) a
|
||||||
-> NValueF p m a
|
-> NValueF p m a
|
||||||
unliftNValueF run = hoistNValueF lift run
|
unliftNValueF = hoistNValueF
|
||||||
|
|
||||||
type MonadDataContext f (m :: * -> *)
|
type MonadDataContext f (m :: * -> *)
|
||||||
= (Comonad f, Applicative f, Traversable f, Monad m)
|
= (Comonad f, Applicative f, Traversable f, Monad m)
|
||||||
|
@ -167,76 +181,69 @@ type MonadDataContext f (m :: * -> *)
|
||||||
newtype NValue' t f m a = NValue { _nValue :: f (NValueF (NValue t f m) m a) }
|
newtype NValue' t f m a = NValue { _nValue :: f (NValueF (NValue t f m) m a) }
|
||||||
deriving (Generic, Typeable, Functor, Foldable)
|
deriving (Generic, Typeable, Functor, Foldable)
|
||||||
|
|
||||||
instance Show r => Show (NValueF p m r) where
|
|
||||||
showsPrec = flip go where
|
|
||||||
go (NVConstantF atom ) = showsCon1 "NVConstant" atom
|
|
||||||
go (NVStrF ns ) = showsCon1 "NVStr" (hackyStringIgnoreContext ns)
|
|
||||||
go (NVListF lst ) = showsCon1 "NVList" lst
|
|
||||||
go (NVSetF attrs _) = showsCon1 "NVSet" attrs
|
|
||||||
go (NVClosureF p _) = showsCon1 "NVClosure" p
|
|
||||||
go (NVPathF p ) = showsCon1 "NVPath" p
|
|
||||||
go (NVBuiltinF name _ ) = showsCon1 "NVBuiltin" name
|
|
||||||
|
|
||||||
showsCon1 :: Show a => String -> a -> Int -> String -> String
|
|
||||||
showsCon1 con a d =
|
|
||||||
showParen (d > 10) $ showString (con ++ " ") . showsPrec 11 a
|
|
||||||
|
|
||||||
instance (Comonad f, Show a) => Show (NValue' t f m a) where
|
instance (Comonad f, Show a) => Show (NValue' t f m a) where
|
||||||
show (NValue (extract -> v)) = show v
|
show (NValue (extract -> v)) = show v
|
||||||
|
|
||||||
instance Comonad f => Show1 (NValue' t f m) where
|
instance Comonad f => Show1 (NValue' t f m) where
|
||||||
liftShowsPrec sp sl p = \case
|
liftShowsPrec sp sl p = \case
|
||||||
NVConstant atom -> showsUnaryWith showsPrec "NVConstantF" p atom
|
NVConstant' atom -> showsUnaryWith showsPrec "NVConstantF" p atom
|
||||||
NVStr ns ->
|
NVStr' ns ->
|
||||||
showsUnaryWith showsPrec "NVStrF" p (hackyStringIgnoreContext ns)
|
showsUnaryWith showsPrec "NVStrF" p (hackyStringIgnoreContext ns)
|
||||||
NVList lst -> showsUnaryWith (liftShowsPrec sp sl) "NVListF" p lst
|
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
|
NVPath' path -> showsUnaryWith showsPrec "NVPathF" p path
|
||||||
NVClosure c _ -> showsUnaryWith showsPrec "NVClosureF" p c
|
NVClosure' c _ -> showsUnaryWith showsPrec "NVClosureF" p c
|
||||||
NVBuiltin name _ -> showsUnaryWith showsPrec "NVBuiltinF" p name
|
NVBuiltin' name _ -> showsUnaryWith showsPrec "NVBuiltinF" p name
|
||||||
_ -> error "Pattern synonyms mask coverage"
|
_ -> error "Pattern synonyms mask coverage"
|
||||||
|
|
||||||
type NValue t f m = NValue' t f m t
|
sequenceNValue'
|
||||||
|
|
||||||
sequenceNValue
|
|
||||||
:: (Functor n, Traversable f, Monad m, Applicative n)
|
:: (Functor n, Traversable f, Monad m, Applicative n)
|
||||||
=> (forall x . n x -> m x)
|
=> (forall x . n x -> m x)
|
||||||
-> NValue' t f m (n a)
|
-> NValue' t f m (n a)
|
||||||
-> n (NValue' t f m a)
|
-> n (NValue' t f m a)
|
||||||
sequenceNValue transform (NValue v) =
|
sequenceNValue' transform (NValue v) =
|
||||||
NValue <$> traverse (sequenceNValueF transform) v
|
NValue <$> traverse (sequenceNValueF transform) v
|
||||||
|
|
||||||
bindNValue
|
bindNValue'
|
||||||
:: (Traversable f, Monad m, Monad n)
|
:: (Traversable f, Monad m, Monad n)
|
||||||
=> (forall x . n x -> m x)
|
=> (forall x . n x -> m x)
|
||||||
-> (a -> n b)
|
-> (a -> n b)
|
||||||
-> NValue' t f m a
|
-> NValue' t f m a
|
||||||
-> n (NValue' t f m b)
|
-> n (NValue' t f m b)
|
||||||
bindNValue transform f (NValue v) =
|
bindNValue' transform f (NValue v) =
|
||||||
NValue <$> traverse (bindNValueF transform f) v
|
NValue <$> traverse (bindNValueF transform f) v
|
||||||
|
|
||||||
hoistNValue
|
hoistNValue'
|
||||||
:: (Functor m, Functor n, Functor f)
|
:: (Functor m, Functor n, Functor f)
|
||||||
=> (forall x . n x -> m x)
|
=> (forall x . n x -> m x)
|
||||||
-> (forall x . m x -> n x)
|
-> (forall x . m x -> n x)
|
||||||
-> NValue' t f m a
|
-> NValue' t f m a
|
||||||
-> NValue' t f n a
|
-> NValue' t f n a
|
||||||
hoistNValue run lft (NValue v) =
|
hoistNValue' run lft (NValue v) =
|
||||||
NValue (fmap (lmapNValueF (hoistNValue lft run) . hoistNValueF run lft) v)
|
NValue (fmap (lmapNValueF (hoistNValue lft run) . hoistNValueF lft) v)
|
||||||
|
|
||||||
liftNValue
|
liftNValue'
|
||||||
:: (MonadTrans u, Monad m, Functor (u m), Functor f)
|
:: (MonadTrans u, Monad m, Functor (u m), Functor f)
|
||||||
=> (forall x . u m x -> m x)
|
=> (forall x . u m x -> m x)
|
||||||
-> NValue' t f m a
|
-> NValue' t f m a
|
||||||
-> NValue' t f (u m) a
|
-> NValue' t f (u m) a
|
||||||
liftNValue run = hoistNValue run lift
|
liftNValue' run = hoistNValue' run lift
|
||||||
|
|
||||||
unliftNValue
|
unliftNValue'
|
||||||
:: (MonadTrans u, Monad m, Functor (u m), Functor f)
|
:: (MonadTrans u, Monad m, Functor (u m), Functor f)
|
||||||
=> (forall x . u m x -> m x)
|
=> (forall x . u m x -> m x)
|
||||||
-> NValue' t f (u m) a
|
-> NValue' t f (u m) a
|
||||||
-> NValue' t f m a
|
-> NValue' t f m a
|
||||||
unliftNValue run = hoistNValue lift run
|
unliftNValue' run = hoistNValue' lift run
|
||||||
|
|
||||||
|
iterNValue'
|
||||||
|
:: forall t f m a r
|
||||||
|
. MonadDataContext f m
|
||||||
|
=> (a -> (NValue' t f m a -> r) -> r)
|
||||||
|
-> (NValue' t f m r -> r)
|
||||||
|
-> NValue' t f m a
|
||||||
|
-> r
|
||||||
|
iterNValue' k f = f . fmap (\a -> k a (iterNValue' k f))
|
||||||
|
|
||||||
-- | An 'NValueNF' is a fully evaluated value in normal form. An 'NValue f t m' is
|
-- | An 'NValueNF' is a fully evaluated value in normal form. An 'NValue f t m' is
|
||||||
-- a value in head normal form, where only the "top layer" has been
|
-- a value in head normal form, where only the "top layer" has been
|
||||||
|
@ -248,64 +255,72 @@ unliftNValue run = hoistNValue lift run
|
||||||
-- The 'Free' structure is used here to represent the possibility that
|
-- The 'Free' structure is used here to represent the possibility that
|
||||||
-- cycles may appear during normalization.
|
-- cycles may appear during normalization.
|
||||||
|
|
||||||
type NValueNF t f m = Free (NValue' t f m) t
|
type NValue t f m = Free (NValue' t f m) t
|
||||||
|
type NValueNF t f m = Fix (NValue' t f m)
|
||||||
|
|
||||||
|
hoistNValue
|
||||||
|
:: (Functor m, Functor n, Functor f)
|
||||||
|
=> (forall x . n x -> m x)
|
||||||
|
-> (forall x . m x -> n x)
|
||||||
|
-> NValue t f m
|
||||||
|
-> NValue t f n
|
||||||
|
hoistNValue run lft = hoistFree (hoistNValue' run lft)
|
||||||
|
|
||||||
|
liftNValue
|
||||||
|
:: (MonadTrans u, Monad m, Functor (u m), Functor f)
|
||||||
|
=> (forall x . u m x -> m x)
|
||||||
|
-> NValue t f m
|
||||||
|
-> NValue t f (u m)
|
||||||
|
liftNValue run = hoistNValue run lift
|
||||||
|
|
||||||
|
unliftNValue
|
||||||
|
:: (MonadTrans u, Monad m, Functor (u m), Functor f)
|
||||||
|
=> (forall x . u m x -> m x)
|
||||||
|
-> NValue t f (u m)
|
||||||
|
-> NValue t f m
|
||||||
|
unliftNValue run = hoistNValue lift run
|
||||||
|
|
||||||
iterNValue
|
iterNValue
|
||||||
:: forall t f m a r
|
:: forall t f m r
|
||||||
. MonadDataContext f m
|
. MonadDataContext f m
|
||||||
=> (a -> (NValue' t f m a -> r) -> r)
|
=> (t -> (NValue t f m -> r) -> r)
|
||||||
-> (NValue' t f m r -> r)
|
-> (NValue' t f m r -> r)
|
||||||
-> NValue' t f m a
|
-> NValue t f m
|
||||||
-> r
|
-> r
|
||||||
iterNValue k f = f . fmap (\a -> k a (iterNValue k f))
|
iterNValue k f = iter f . fmap (\t -> k t (iterNValue k f))
|
||||||
|
|
||||||
iterNValueM
|
iterNValueM
|
||||||
:: (MonadDataContext f m, Monad n)
|
:: (MonadDataContext f m, Monad n)
|
||||||
=> (forall x . n x -> m x)
|
=> (forall x . n x -> m x)
|
||||||
-> (a -> (NValue' t f m a -> n r) -> n r)
|
-> (t -> (NValue t f m -> n r) -> n r)
|
||||||
-> (NValue' t f m r -> n r)
|
-> (NValue' t f m (n r) -> n r)
|
||||||
-> NValue' t f m a
|
-> NValue t f m
|
||||||
-> n r
|
-> n r
|
||||||
iterNValueM transform k f =
|
iterNValueM transform k f =
|
||||||
f <=< bindNValue transform (\a -> k a (iterNValueM transform k f))
|
iterM f <=< go . fmap (\t -> k t (iterNValueM transform k f))
|
||||||
|
where
|
||||||
|
go (Pure x) = Pure <$> x
|
||||||
|
go (Free fa) = Free <$> bindNValue' transform go fa
|
||||||
|
|
||||||
iterNValueNF
|
iterNValueNF
|
||||||
:: MonadDataContext f m
|
:: MonadDataContext f m
|
||||||
=> (t -> r)
|
=> (NValue' t f m r -> r)
|
||||||
-> (NValue' t f m r -> r)
|
|
||||||
-> NValueNF t f m
|
-> NValueNF t f m
|
||||||
-> r
|
-> r
|
||||||
iterNValueNF k f = iter f . fmap k
|
iterNValueNF = cata
|
||||||
|
|
||||||
iterNValueNFM
|
|
||||||
:: forall f m n t r
|
|
||||||
. (MonadDataContext f m, Monad n)
|
|
||||||
=> (forall x . n x -> m x)
|
|
||||||
-> (t -> n r)
|
|
||||||
-> (NValue' t f m (n r) -> n r)
|
|
||||||
-> NValueNF t f m
|
|
||||||
-> n r
|
|
||||||
iterNValueNFM transform k f v =
|
|
||||||
iterM f =<< go (fmap k v)
|
|
||||||
where
|
|
||||||
go (Pure a ) = Pure <$> a
|
|
||||||
go (Free fa) = Free <$> bindNValue transform go fa
|
|
||||||
|
|
||||||
nValueFromNF
|
nValueFromNF
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> NValueNF t f m
|
=> NValueNF t f m
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
nValueFromNF = iterNValueNF f (fmap wrapValue)
|
nValueFromNF = fmap absurd . fixToFree
|
||||||
where
|
|
||||||
f t = query t cyc id
|
|
||||||
cyc = nvStr (principledMakeNixStringWithoutContext "<CYCLE>")
|
|
||||||
|
|
||||||
nValueToNF
|
nValueToNF
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> (t -> (NValue t f m -> NValueNF t f m) -> NValueNF t f m)
|
=> (t -> (NValue t f m -> NValueNF t f m) -> NValueNF t f m)
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
-> NValueNF t f m
|
-> NValueNF t f m
|
||||||
nValueToNF k = iterNValue k Free
|
nValueToNF k = iterNValue k Fix
|
||||||
|
|
||||||
nValueToNFM
|
nValueToNFM
|
||||||
:: (MonadDataContext f m, Monad n)
|
:: (MonadDataContext f m, Monad n)
|
||||||
|
@ -313,91 +328,124 @@ nValueToNFM
|
||||||
-> (t -> (NValue t f m -> n (NValueNF t f m)) -> n (NValueNF t f m))
|
-> (t -> (NValue t f m -> n (NValueNF t f m)) -> n (NValueNF t f m))
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
-> n (NValueNF t f m)
|
-> n (NValueNF t f m)
|
||||||
nValueToNFM transform k = iterNValueM transform k $ pure . Free
|
nValueToNFM transform k = iterNValueM transform k undefined
|
||||||
|
|
||||||
pattern NVConstant x <- NValue (extract -> NVConstantF x)
|
pattern NVThunk t <- Pure t
|
||||||
pattern NVConstantNF x <- Free (NValue (extract -> NVConstantF x))
|
|
||||||
|
|
||||||
|
nvThunk :: Applicative f => t -> NValue t f m
|
||||||
|
nvThunk = Pure
|
||||||
|
|
||||||
|
pattern NVConstant' x <- NValue (extract -> NVConstantF x)
|
||||||
|
pattern NVConstant x <- Free (NVConstant' x)
|
||||||
|
pattern NVConstantNF x <- Fix (NVConstant' x)
|
||||||
|
|
||||||
|
nvConstant' :: Applicative f => NAtom -> NValue' t f m r
|
||||||
|
nvConstant' x = NValue (pure (NVConstantF x))
|
||||||
nvConstant :: Applicative f => NAtom -> NValue t f m
|
nvConstant :: Applicative f => NAtom -> NValue t f m
|
||||||
nvConstant x = NValue (pure (NVConstantF x))
|
nvConstant x = Free (NValue (pure (NVConstantF x)))
|
||||||
nvConstantNF :: Applicative f => NAtom -> NValueNF t f m
|
nvConstantNF :: Applicative f => NAtom -> NValueNF t f m
|
||||||
nvConstantNF x = Free (NValue (pure (NVConstantF x)))
|
nvConstantNF x = Fix (NValue (pure (NVConstantF x)))
|
||||||
|
|
||||||
pattern NVStr ns <- NValue (extract -> NVStrF ns)
|
pattern NVStr' ns <- NValue (extract -> NVStrF ns)
|
||||||
pattern NVStrNF ns <- Free (NValue (extract -> NVStrF ns))
|
pattern NVStr ns <- Free (NVStr' ns)
|
||||||
|
pattern NVStrNF ns <- Fix (NVStr' ns)
|
||||||
|
|
||||||
|
nvStr' :: Applicative f => NixString -> NValue' t f m r
|
||||||
|
nvStr' ns = NValue (pure (NVStrF ns))
|
||||||
nvStr :: Applicative f => NixString -> NValue t f m
|
nvStr :: Applicative f => NixString -> NValue t f m
|
||||||
nvStr ns = NValue (pure (NVStrF ns))
|
nvStr ns = Free (NValue (pure (NVStrF ns)))
|
||||||
nvStrNF :: Applicative f => NixString -> NValueNF t f m
|
nvStrNF :: Applicative f => NixString -> NValueNF t f m
|
||||||
nvStrNF ns = Free (NValue (pure (NVStrF ns)))
|
nvStrNF ns = Fix (NValue (pure (NVStrF ns)))
|
||||||
|
|
||||||
pattern NVPath x <- NValue (extract -> NVPathF x)
|
pattern NVPath' x <- NValue (extract -> NVPathF x)
|
||||||
pattern NVPathNF x <- Free (NValue (extract -> NVPathF x))
|
pattern NVPath x <- Free (NVPath' x)
|
||||||
|
pattern NVPathNF x <- Fix (NVPath' x)
|
||||||
|
|
||||||
|
nvPath' :: Applicative f => FilePath -> NValue' t f m r
|
||||||
|
nvPath' x = NValue (pure (NVPathF x))
|
||||||
nvPath :: Applicative f => FilePath -> NValue t f m
|
nvPath :: Applicative f => FilePath -> NValue t f m
|
||||||
nvPath x = NValue (pure (NVPathF x))
|
nvPath x = Free (NValue (pure (NVPathF x)))
|
||||||
nvPathNF :: Applicative f => FilePath -> NValueNF t f m
|
nvPathNF :: Applicative f => FilePath -> NValueNF t f m
|
||||||
nvPathNF x = Free (NValue (pure (NVPathF x)))
|
nvPathNF x = Fix (NValue (pure (NVPathF x)))
|
||||||
|
|
||||||
pattern NVList l <- NValue (extract -> NVListF l)
|
pattern NVList' l <- NValue (extract -> NVListF l)
|
||||||
pattern NVListNF l <- Free (NValue (extract -> NVListF l))
|
pattern NVList l <- Free (NVList' l)
|
||||||
|
pattern NVListNF l <- Fix (NVList' l)
|
||||||
|
|
||||||
nvList :: Applicative f => [t] -> NValue t f m
|
nvList' :: Applicative f => [r] -> NValue' t f m r
|
||||||
nvList l = NValue (pure (NVListF l))
|
nvList' l = NValue (pure (NVListF l))
|
||||||
|
nvList :: Applicative f => [NValue t f m] -> NValue t f m
|
||||||
|
nvList l = Free (NValue (pure (NVListF l)))
|
||||||
nvListNF :: Applicative f => [NValueNF t f m] -> NValueNF t f m
|
nvListNF :: Applicative f => [NValueNF t f m] -> NValueNF t f m
|
||||||
nvListNF l = Free (NValue (pure (NVListF l)))
|
nvListNF l = Fix (NValue (pure (NVListF l)))
|
||||||
|
|
||||||
pattern NVSet s x <- NValue (extract -> NVSetF s x)
|
pattern NVSet' s x <- NValue (extract -> NVSetF s x)
|
||||||
pattern NVSetNF s x <- Free (NValue (extract -> NVSetF s x))
|
pattern NVSet s x <- Free (NVSet' s x)
|
||||||
|
pattern NVSetNF s x <- Fix (NVSet' s x)
|
||||||
|
|
||||||
|
nvSet' :: Applicative f
|
||||||
|
=> HashMap Text r -> HashMap Text SourcePos -> NValue' t f m r
|
||||||
|
nvSet' s x = NValue (pure (NVSetF s x))
|
||||||
nvSet :: Applicative f
|
nvSet :: Applicative f
|
||||||
=> HashMap Text t -> HashMap Text SourcePos -> NValue t f m
|
=> HashMap Text (NValue t f m) -> HashMap Text SourcePos -> NValue t f m
|
||||||
nvSet s x = NValue (pure (NVSetF s x))
|
nvSet s x = Free (NValue (pure (NVSetF s x)))
|
||||||
nvSetNF :: Applicative f
|
nvSetNF :: Applicative f
|
||||||
=> HashMap Text (NValueNF t f m) -> HashMap Text SourcePos -> NValueNF t f m
|
=> HashMap Text (NValueNF t f m) -> HashMap Text SourcePos
|
||||||
nvSetNF s x = Free (NValue (pure (NVSetF s x)))
|
-> NValueNF t f m
|
||||||
|
nvSetNF s x = Fix (NValue (pure (NVSetF s x)))
|
||||||
|
|
||||||
pattern NVClosure x f <- NValue (extract -> NVClosureF x f)
|
pattern NVClosure' x f <- NValue (extract -> NVClosureF x f)
|
||||||
pattern NVClosureNF x f <- Free (NValue (extract -> NVClosureF x f))
|
pattern NVClosure x f <- Free (NVClosure' x f)
|
||||||
|
pattern NVClosureNF x f <- Fix (NVClosure' x f)
|
||||||
|
|
||||||
nvClosure :: Applicative f
|
nvClosure' :: (Applicative f, Functor m)
|
||||||
=> Params () -> (m (NValue t f m) -> m t) -> NValue t f m
|
=> Params () -> (NValue t f m -> m r) -> NValue' t f m r
|
||||||
nvClosure x f = NValue (pure (NVClosureF x f))
|
nvClosure' x f = NValue (pure (NVClosureF x f))
|
||||||
|
nvClosure :: (Applicative f, Functor m)
|
||||||
|
=> Params () -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
|
||||||
|
nvClosure x f = Free (NValue (pure (NVClosureF x f)))
|
||||||
nvClosureNF :: Applicative f
|
nvClosureNF :: Applicative f
|
||||||
=> Params () -> (m (NValue t f m) -> m (NValueNF t f m)) -> NValueNF t f m
|
=> Params () -> (NValue t f m -> m (NValueNF t f m))
|
||||||
nvClosureNF x f = Free (NValue (pure (NVClosureF x f)))
|
-> NValueNF t f m
|
||||||
|
nvClosureNF x f = Fix (NValue (pure (NVClosureF x f)))
|
||||||
|
|
||||||
pattern NVBuiltin name f <- NValue (extract -> NVBuiltinF name f)
|
pattern NVBuiltin' name f <- NValue (extract -> NVBuiltinF name f)
|
||||||
pattern NVBuiltinNF name f <- Free (NValue (extract -> NVBuiltinF name f))
|
pattern NVBuiltin name f <- Free (NVBuiltin' name f)
|
||||||
|
pattern NVBuiltinNF name f <- Fix (NVBuiltin' name f)
|
||||||
|
|
||||||
nvBuiltin :: Applicative f
|
nvBuiltin' :: (Applicative f, Functor m)
|
||||||
=> String -> (m (NValue t f m) -> m t) -> NValue t f m
|
=> String -> (NValue t f m -> m r) -> NValue' t f m r
|
||||||
nvBuiltin name f = NValue (pure (NVBuiltinF name f))
|
nvBuiltin' name f = NValue (pure (NVBuiltinF name f))
|
||||||
|
nvBuiltin :: (Applicative f, Functor m)
|
||||||
|
=> String -> (NValue t f m -> m (NValue t f m)) -> NValue t f m
|
||||||
|
nvBuiltin name f =
|
||||||
|
Free (NValue (pure (NVBuiltinF name f)))
|
||||||
nvBuiltinNF :: Applicative f
|
nvBuiltinNF :: Applicative f
|
||||||
=> String -> (m (NValue t f m) -> m (NValueNF t f m)) -> NValueNF t f m
|
=> String -> (NValue t f m -> m (NValueNF t f m))
|
||||||
nvBuiltinNF name f = Free (NValue (pure (NVBuiltinF name f)))
|
-> NValueNF t f m
|
||||||
|
nvBuiltinNF name f = Fix (NValue (pure (NVBuiltinF name f)))
|
||||||
|
|
||||||
builtin
|
builtin
|
||||||
:: forall m f t
|
:: forall m f t
|
||||||
. (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
. (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> String
|
=> String
|
||||||
-> (m (NValue t f m) -> m (NValue t f m))
|
-> (NValue t f m -> m (NValue t f m))
|
||||||
-> m (NValue t f m)
|
-> m (NValue t f m)
|
||||||
builtin name f = return $ nvBuiltin name $ \a -> thunk $ f a
|
builtin name f = return $ nvBuiltin name $ \a -> f a
|
||||||
|
|
||||||
builtin2
|
builtin2
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> String
|
=> String
|
||||||
-> (m (NValue t f m) -> m (NValue t f m) -> m (NValue t f m))
|
-> (NValue t f m -> NValue t f m -> m (NValue t f m))
|
||||||
-> m (NValue t f m)
|
-> m (NValue t f m)
|
||||||
builtin2 name f = builtin name $ \a -> builtin name $ \b -> f a b
|
builtin2 name f = builtin name $ \a -> builtin name $ \b -> f a b
|
||||||
|
|
||||||
builtin3
|
builtin3
|
||||||
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
:: (MonadThunk t m (NValue t f m), MonadDataContext f m)
|
||||||
=> String
|
=> String
|
||||||
-> ( m (NValue t f m)
|
-> ( NValue t f m
|
||||||
-> m (NValue t f m)
|
-> NValue t f m
|
||||||
-> m (NValue t f m)
|
-> NValue t f m
|
||||||
-> m (NValue t f m)
|
-> m (NValue t f m)
|
||||||
)
|
)
|
||||||
-> m (NValue t f m)
|
-> m (NValue t f m)
|
||||||
|
@ -454,7 +502,7 @@ describeValue = \case
|
||||||
TBuiltin -> "a builtin function"
|
TBuiltin -> "a builtin function"
|
||||||
|
|
||||||
data ValueFrame t f m
|
data ValueFrame t f m
|
||||||
= ForcingThunk
|
= ForcingThunk t
|
||||||
| ConcerningValue (NValue t f m)
|
| ConcerningValue (NValue t f m)
|
||||||
| Comparison (NValue t f m) (NValue t f m)
|
| Comparison (NValue t f m) (NValue t f m)
|
||||||
| Addition (NValue t f m) (NValue t f m)
|
| Addition (NValue t f m) (NValue t f m)
|
||||||
|
@ -463,9 +511,10 @@ data ValueFrame t f m
|
||||||
| Coercion ValueType ValueType
|
| Coercion ValueType ValueType
|
||||||
| CoercionToJson (NValue t f m)
|
| CoercionToJson (NValue t f m)
|
||||||
| CoercionFromJson A.Value
|
| CoercionFromJson A.Value
|
||||||
| ExpectationNF ValueType (NValueNF t f m)
|
| forall r. Show r => Expectation ValueType (NValue' t f m r)
|
||||||
| Expectation ValueType (NValue t f m)
|
deriving Typeable
|
||||||
deriving (Show, Typeable)
|
|
||||||
|
deriving instance (Comonad f, Show t) => Show (ValueFrame t f m)
|
||||||
|
|
||||||
type MonadDataErrorContext t f m
|
type MonadDataErrorContext t f m
|
||||||
= (Show t, Typeable t, Typeable m, Typeable f, MonadDataContext f m)
|
= (Show t, Typeable t, Typeable m, Typeable f, MonadDataContext f m)
|
||||||
|
|
|
@ -38,6 +38,7 @@ import Control.Monad.Trans.Class
|
||||||
import Control.Monad.Trans.Except
|
import Control.Monad.Trans.Except
|
||||||
import Data.Align
|
import Data.Align
|
||||||
import Data.Eq.Deriving
|
import Data.Eq.Deriving
|
||||||
|
import Data.Fix
|
||||||
import Data.Functor.Classes
|
import Data.Functor.Classes
|
||||||
import Data.Functor.Identity
|
import Data.Functor.Identity
|
||||||
import qualified Data.HashMap.Lazy as M
|
import qualified Data.HashMap.Lazy as M
|
||||||
|
@ -164,30 +165,30 @@ compareAttrSets f eq lm rm = runIdentity
|
||||||
$ compareAttrSetsM (\t -> Identity (f t)) (\x y -> Identity (eq x y)) lm rm
|
$ compareAttrSetsM (\t -> Identity (f t)) (\x y -> Identity (eq x y)) lm rm
|
||||||
|
|
||||||
valueEqM
|
valueEqM
|
||||||
:: (MonadThunk t m (NValue t f m), Comonad f)
|
:: forall t f m. (MonadThunk t m (NValue t f m), Comonad f)
|
||||||
=> NValue t f m
|
=> NValue t f m
|
||||||
-> NValue t f m
|
-> NValue t f m
|
||||||
-> m Bool
|
-> m Bool
|
||||||
valueEqM (NValue (extract -> x)) (NValue (extract -> y)) = valueFEqM
|
valueEqM (Pure x) (Pure y) = thunkEqM x y
|
||||||
(compareAttrSetsM f thunkEqM)
|
valueEqM (Pure _) _ = pure False
|
||||||
thunkEqM
|
valueEqM _ (Pure _) = pure False
|
||||||
x
|
valueEqM (Free (NValue (extract -> x))) (Free (NValue (extract -> y))) =
|
||||||
y
|
valueFEqM (compareAttrSetsM f valueEqM) valueEqM x y
|
||||||
where
|
where
|
||||||
f t = force t $ \case
|
f (Pure t) = force t $ \case
|
||||||
NVStr s -> pure $ Just s
|
NVStr s -> pure $ Just s
|
||||||
_ -> pure Nothing
|
_ -> pure Nothing
|
||||||
|
f (Free v) = case v of
|
||||||
|
NVStr' s -> pure $ Just s
|
||||||
|
_ -> pure Nothing
|
||||||
|
|
||||||
valueNFEq :: Comonad f => NValueNF t f m -> NValueNF t f m -> Bool
|
valueNFEq :: Comonad f => NValueNF t f m -> NValueNF t f m -> Bool
|
||||||
valueNFEq (Pure _) (Pure _) = False
|
valueNFEq (Fix (NValue (extract -> x))) (Fix (NValue (extract -> y))) =
|
||||||
valueNFEq (Pure _) (Free _) = False
|
|
||||||
valueNFEq (Free _) (Pure _) = False
|
|
||||||
valueNFEq (Free (NValue (extract -> x))) (Free (NValue (extract -> y))) =
|
|
||||||
valueFEq (compareAttrSets f valueNFEq) valueNFEq x y
|
valueFEq (compareAttrSets f valueNFEq) valueNFEq x y
|
||||||
where
|
where
|
||||||
f (Pure _ ) = Nothing
|
f = \case
|
||||||
f (Free (NVStr s)) = Just s
|
NVStrNF s -> Just s
|
||||||
f _ = Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
instance Eq1 (NValueF p m) where
|
instance Eq1 (NValueF p m) where
|
||||||
liftEq _ (NVConstantF x) (NVConstantF y) = x == y
|
liftEq _ (NVConstantF x) (NVConstantF y) = x == y
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
{-# LANGUAGE FunctionalDependencies #-}
|
||||||
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
|
|
||||||
|
module Nix.Value.Monad where
|
||||||
|
|
||||||
|
class MonadValue v m where
|
||||||
|
defer :: m v -> m v
|
||||||
|
demand :: v -> (v -> m r) -> m r
|
Loading…
Reference in New Issue