Skip to content

Can NixString be the NAtom? #534

@Anton-Latukha

Description

@Anton-Latukha

Upon progressing with #509, in the current issue, I am wrestling with existential higher-rank type inference. And everything came into the one type level puzzle piece: Expected NAtom, actual type NixString.

And I thought why not both? It seems like it should be so.


It seems like Nix-native NixString ({Text, Hash}) indeed can be represented with an NAtom since it is a literal pun, and one of the Nix basic types.

In Strings.hs there is extract & create & modify and such:

hnix/src/Nix/String.hs

Lines 225 to 227 in 0305b52

-- | Get the contents of a 'NixString' and write its context into the resulting set.
extractNixString :: Monad m => NixString -> WithStringContextT m Text
extractNixString (NixString s c) = WithStringContextT $ tell c >> return s

hnix/src/Nix/String.hs

Lines 201 to 208 in 0305b52

-- | Create a NixString using a singleton context
principledMakeNixStringWithSingletonContext
:: Text -> StringContext -> NixString
principledMakeNixStringWithSingletonContext s c = NixString s (S.singleton c)
-- | Create a NixString from a Text and context
principledMakeNixString :: Text -> S.HashSet StringContext -> NixString
principledMakeNixString s c = NixString s c


And in Atom.hs everything seems welcoming it also:

hnix/src/Nix/Atoms.hs

Lines 21 to 50 in 0305b52

-- | Atoms are values that evaluate to themselves. This means that
-- they appear in both the parsed AST (in the form of literals) and
-- the evaluated form.
data NAtom
-- | An integer. The c nix implementation currently only supports
-- integers that fit in the range of 'Int64'.
= NInt Integer
-- | A floating point number
| NFloat Float
-- | Booleans.
| NBool Bool
-- | Null values. There's only one of this variant.
| NNull
deriving (Eq, Ord, Generic, Typeable, Data, Show, Read, NFData,
Hashable)
#ifdef MIN_VERSION_serialise
instance Serialise NAtom
#endif
-- | Translate an atom into its nix representation.
atomText :: NAtom -> Text
atomText (NInt i) = pack (show i)
atomText (NFloat f) = pack (showNixFloat f)
where
showNixFloat x
| x `mod'` 1 /= 0 = show x
| otherwise = show (truncate x :: Int)
atomText (NBool b) = if b then "true" else "false"
atomText NNull = "null"

At least that should help type system and me, simplify some type inference, and probably would allow to even better formalize the text & string functions.

Is this sane idea?

Metadata

Metadata

Assignees

No one assigned

    Labels

    API changeRequires major release.challengingMay require somewhat complex changes; not recommend if you aren't familiar with the codebasedialecticThe art of finding the truth.stringcontexttaken

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions