Skip to content

Commit

Permalink
Turn ElField into a newtype (VinylRecords#150)
Browse files Browse the repository at this point in the history
* Saves a 1 word per field
* Improves accessor performance significantly both for Rec as well as ARec
  • Loading branch information
Philonous committed May 27, 2021
1 parent 5a996ac commit 4361e76
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Data/Vinyl/Class/Method.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Data/Vinyl/Derived.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions Data/Vinyl/Functor.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 4361e76

Please sign in to comment.