Expand the hashability of NExpr and related structures

This commit is contained in:
John Wiegley 2018-04-17 13:50:40 -07:00
parent 64a10669ac
commit 9d2834099e

View file

@ -34,6 +34,7 @@ import Data.Eq.Deriving
import Data.Fix
import Data.Functor.Classes
import Data.Hashable
import Data.Hashable.Lifted
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NE
import Data.Monoid
@ -54,6 +55,8 @@ import qualified Type.Reflection as Reflection
type VarName = Text
instance Hashable1 NonEmpty -- jww (2018-04-17): an unfortunate orphan
-- | The main nix expression type. This is polymorphic so that it can be made
-- a functor, which allows us to traverse expressions and map functions over
-- them. The actual 'NExpr' type is a fixed point of this functor, defined
@ -100,7 +103,8 @@ data NExprF r
| NAssert !r !r
-- ^ Assert that the first returns true before evaluating the second.
deriving (Ord, Eq, Generic, Generic1, Typeable, Data, Functor,
Foldable, Traversable, Show, NFData, NFData1, Serialise, Hashable)
Foldable, Traversable, Show, NFData, NFData1, Serialise,
Hashable, Hashable1)
-- | We make an `IsString` for expressions, where the string is interpreted
-- as an identifier. This is the most common use-case...
@ -113,7 +117,6 @@ instance Lift (Fix NExprF) where
Just HRefl -> Just [| pack $(liftString $ unpack b) |]
Nothing -> Nothing
-- | The monomorphic expression type is a fixed point of the polymorphic one.
type NExpr = Fix NExprF
@ -127,7 +130,8 @@ data Binding r
-- ^ Using a name already in scope, such as @inherit x;@ which is shorthand
-- for @x = x;@ or @inherit (x) y;@ which means @y = x.y;@.
deriving (Generic, Generic1, Typeable, Data, Ord, Eq, Functor,
Foldable, Traversable, Show, NFData, NFData1, Serialise, Hashable)
Foldable, Traversable, Show, NFData, NFData1, Serialise,
Hashable, Hashable1)
-- | @Params@ represents all the ways the formal parameters to a
-- function can be represented.
@ -139,7 +143,8 @@ data Params r
-- bind to the set in the function body. The bool indicates whether it is
-- variadic or not.
deriving (Ord, Eq, Generic, Generic1, Typeable, Data, Functor, Show,
Foldable, Traversable, NFData, NFData1, Serialise, Hashable)
Foldable, Traversable, NFData, NFData1, Serialise,
Hashable, Hashable1)
-- This uses an association list because nix XML serialization preserves the
-- order of the param set.
@ -152,7 +157,16 @@ instance IsString (Params r) where
-- antiquoted (surrounded by ${...}) or plain (not antiquoted).
data Antiquoted (v :: *) (r :: *) = Plain !v | EscapedNewline | Antiquoted !r
deriving (Ord, Eq, Generic, Generic1, Typeable, Data, Functor, Foldable,
Traversable, Show, Read, NFData, NFData1, Serialise, Hashable)
Traversable, Show, Read, NFData, NFData1, Serialise,
Hashable, Hashable1)
instance Hashable2 Antiquoted where
liftHashWithSalt2 ha _ salt (Plain a) =
ha (salt `hashWithSalt` (0 :: Int)) a
liftHashWithSalt2 _ _ salt EscapedNewline =
salt `hashWithSalt` (1 :: Int)
liftHashWithSalt2 _ hb salt (Antiquoted b) =
hb (salt `hashWithSalt` (2 :: Int)) b
-- | An 'NString' is a list of things that are either a plain string
-- or an antiquoted expression. After the antiquotes have been evaluated,
@ -166,7 +180,8 @@ data NString r
-- their indentation will be stripped, but the amount stripped is
-- remembered.
deriving (Eq, Ord, Generic, Generic1, Typeable, Data, Functor, Foldable,
Traversable, Show, Read, NFData, NFData1, Serialise, Hashable)
Traversable, Show, Read, NFData, NFData1, Serialise,
Hashable, Hashable1)
-- | For the the 'IsString' instance, we use a plain doublequoted string.
instance IsString (NString r) where
@ -232,6 +247,12 @@ instance Eq1 NKeyName where
liftEq _ (StaticKey a _) (StaticKey b _) = a == b
liftEq _ _ _ = False
instance Hashable1 NKeyName where
liftHashWithSalt h salt (DynamicKey a) =
liftHashWithSalt2 (liftHashWithSalt h) h (salt `hashWithSalt` (0 :: Int)) a
liftHashWithSalt _ salt (StaticKey n p) =
salt `hashWithSalt` (1 :: Int) `hashWithSalt` n `hashWithSalt` p
-- Deriving this instance automatically is not possible because @r@
-- occurs not only as last argument in @Antiquoted (NString r) r@
instance Show1 NKeyName where