packages feed

hkd-records 0.0.4 → 0.0.5

raw patch · 2 files changed

+38/−3 lines, 2 filesdep +template-haskell

Dependencies added: template-haskell

Files

hkd-records.cabal view
@@ -1,5 +1,5 @@ name:                hkd-records-version:             0.0.4+version:             0.0.5 cabal-version:       >=1.10 synopsis:  higher kinded record operations description: make higher kinded records great again@@ -22,7 +22,8 @@   default-language: Haskell2010   Build-depends: base >= 3 && < 5,                  hkd >= 0.1 && < 0.3,-                 text >= 1.2 && < 1.3+                 text >= 1.2 && < 1.3,+                 template-haskell >= 2.14.0.0   hs-source-dirs:     src                    Exposed-Modules:
src/Data/HKD/Records.hs view
@@ -18,6 +18,7 @@ {-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE TemplateHaskell #-}  {-| Module      : Data.HKD.Records@@ -54,7 +55,7 @@  module Data.HKD.Records (   FieldNames(..),-  Dict(..), FDicts(..),+  Dict(..), FDicts(..), newConstraint,   RecordCons(..), FieldCons(..), End(..),   fzipManyWith, ftoList, Lens', FLens(..),   FLenses(..)) where@@ -67,6 +68,7 @@ import qualified Data.Text as Text import Data.Proxy import Data.Monoid+import Language.Haskell.TH  class FieldNames t where   -- | get the fieldNames from each field as a (Const Text).  Can be@@ -130,6 +132,38 @@   genFdict = M1 $ M1 $ genFdict   {-# INLINE genFdict #-} +tupleToList :: Type -> Maybe [Type]+tupleToList (AppT (TupleT _) t) = Just [t]+tupleToList (AppT t1 t2) = (t2:) <$> tupleToList t1+tupleToList _ = Nothing++-- | Template Haskell function to create a new constraint from a list+-- of existing constraints.  Unlike a type synonym or type family,+-- this constraint can be partially applied, and used inside `FDicts`.+-- This just generates a class and instance without member functions.+--+-- example usage:+-- +-- > newConstraint "MyConstraints"+-- >   [t| forall r . (FFoldable r, FRepeat r, FieldNames r) |]+--+-- This creates a constraint @MyConstraints :: ((k -> Type) -> Type) -> Type@,+-- which combines the constraint `FFoldable`, `FRepeat` and `FieldNames`+newConstraint :: String -> Q Type -> Q [Dec]+newConstraint nm defQ = do+  def <- defQ+  let failmsg = "expected form for constraint body: forall c . (Constraint1 c, Constraint2 c, ...)"+  case def of+    ForallT [PlainTV tyvar] [] body ->+      case tupleToList body of+        Nothing -> fail failmsg+        Just l -> sequence+          [ classD (pure (reverse l)) (mkName nm) [PlainTV tyvar] [] []+          , instanceD (pure (reverse l)) (appT (conT $ mkName nm) (varT tyvar))+            []+          ]+    _ -> fail failmsg+   infixr 5 :> infixr 5 :~>