Skip to content
This repository has been archived by the owner on May 25, 2022. It is now read-only.

Add Data instance to Record #56

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composite-base/composite-base.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ library
default-extensions:
ConstraintKinds
DataKinds
DeriveDataTypeable
FlexibleContexts
FlexibleInstances
FunctionalDependencies
Expand Down
1 change: 1 addition & 0 deletions composite-base/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies:
default-extensions:
- ConstraintKinds
- DataKinds
- DeriveDataTypeable
- FlexibleContexts
- FlexibleInstances
- FunctionalDependencies
Expand Down
28 changes: 28 additions & 0 deletions composite-base/src/Composite/Record.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import qualified Data.Vinyl.TypeLevel as Vinyl
import Data.Vinyl.XRec(IsoHKD(HKD, toHKD, unHKD))
import Foreign.Storable (Storable)
import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)
import Data.Data (Data (gfoldl, toConstr, dataTypeOf, gunfold), Typeable, DataType, Constr, Fixity (Prefix, Infix), mkDataType, constrIndex, mkConstr)

-- FIXME this file is a big bin of random stuff, and should be at least organized if not split up.

Expand Down Expand Up @@ -102,6 +103,33 @@ instance KnownSymbol s => IsoHKD Identity (s :-> a) where
unHKD = Identity . Val
toHKD (Identity (Val x)) = x

deriving instance (Typeable k, Data k, KnownSymbol s) => Data (s :-> k)

rnilConstr :: Constr
rnilConstr = mkConstr recDataType "RNil" [] Prefix

rconsConstr :: Constr
rconsConstr = mkConstr recDataType "(:&)" [] Infix

recDataType :: DataType
recDataType = mkDataType "Data.Vinyl.Core.Rec" [rnilConstr, rconsConstr]

instance Data (Record '[]) where
gfoldl _ z RNil = z RNil
toConstr RNil = rnilConstr
dataTypeOf _ = recDataType
gunfold _ z c = case constrIndex c of
1 -> z RNil
_ -> errorWithoutStackTrace "Data.Data.gunfold(Rec)"

instance (Data x, Typeable xs, Data (Record xs)) => Data (Record (x ': xs)) where
gfoldl f z (x :& xs) = z (:&) `f` x `f` xs
toConstr (_ :& _) = rconsConstr
dataTypeOf _ = recDataType
gunfold k z c = case constrIndex c of
2 -> k (k (z (:&)))
_ -> errorWithoutStackTrace "Data.Data.gunfold(Rec)"

-- |Convenience function to make an @'Identity' (s ':->' a)@ with a particular symbol, used for named field construction.
--
-- For example:
Expand Down