From 73d73e3a91e8101b6a99836477a483d6ec281eeb Mon Sep 17 00:00:00 2001 From: Philipp Balzarek Date: Wed, 19 May 2021 22:55:33 +0200 Subject: [PATCH] Turn ElField into a newtype (#150) * Saves a 1 word per field * Improves accessor performance significantly both for Rec as well as ARec --- Data/Vinyl/Class/Method.hs | 2 +- Data/Vinyl/Derived.hs | 2 +- Data/Vinyl/Functor.hs | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Data/Vinyl/Class/Method.hs b/Data/Vinyl/Class/Method.hs index d10774a..212c72d 100644 --- a/Data/Vinyl/Class/Method.hs +++ b/Data/Vinyl/Class/Method.hs @@ -142,7 +142,7 @@ data FieldTyper = FieldId | FieldSnd -- | The interpretation function of the 'FieldTyper' symbols. type family ApplyFieldTyper (f :: FieldTyper) (a :: k) :: * where ApplyFieldTyper 'FieldId a = a - ApplyFieldTyper 'FieldSnd '(s, b) = b + ApplyFieldTyper 'FieldSnd a = Snd a -- | A mapping of record contexts into the 'FieldTyper' function -- space. We explicitly match on 'ElField' to pick out the payload diff --git a/Data/Vinyl/Derived.hs b/Data/Vinyl/Derived.hs index a1bd071..6ed7582 100644 --- a/Data/Vinyl/Derived.hs +++ b/Data/Vinyl/Derived.hs @@ -46,7 +46,7 @@ getField :: ElField '(s,t) -> t getField (Field x) = x -- | Get the label name of an 'ElField'. -getLabel :: forall s t. ElField '(s,t) -> String +getLabel :: forall s t. KnownSymbol s => ElField '(s,t) -> String getLabel (Field _) = symbolVal (Proxy::Proxy s) -- | 'ElField' is isomorphic to a functor something like @Compose diff --git a/Data/Vinyl/Functor.hs b/Data/Vinyl/Functor.hs index 8d66021..179fd8a 100644 --- a/Data/Vinyl/Functor.hs +++ b/Data/Vinyl/Functor.hs @@ -42,6 +42,7 @@ import Foreign.Storable import GHC.Generics import GHC.TypeLits import GHC.Types (Type) +import Data.Vinyl.TypeLevel (Snd) {- $introduction This module provides functors and functor compositions @@ -107,8 +108,10 @@ newtype Const (a :: *) (b :: k) -- | A value with a phantom 'Symbol' label. It is not a -- Haskell 'Functor', but it is used in many of the same places a -- 'Functor' is used in vinyl. -data ElField (field :: (Symbol, Type)) where - Field :: KnownSymbol s => !t -> ElField '(s,t) +-- +-- Morally: newtype ElField (s, t) = Field t +-- But GHC doesn't allow that +newtype ElField (t :: (Symbol, Type)) = Field (Snd t) deriving instance Eq t => Eq (ElField '(s,t)) deriving instance Ord t => Ord (ElField '(s,t))