mirror of
https://github.com/khibino/haskell-relational-record.git
synced 2024-12-04 03:53:03 +03:00
persistable-record: add generic definitions of PersistableWidth.
This commit is contained in:
parent
3540f1c053
commit
f28284d17d
@ -1,5 +1,8 @@
|
|||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
|
{-# LANGUAGE TypeOperators #-}
|
||||||
|
{-# LANGUAGE DefaultSignatures #-}
|
||||||
|
|
||||||
-- |
|
-- |
|
||||||
-- Module : Database.Record.Persistable
|
-- Module : Database.Record.Persistable
|
||||||
@ -23,9 +26,10 @@ module Database.Record.Persistable (
|
|||||||
-- * Inference rules for proof objects
|
-- * Inference rules for proof objects
|
||||||
|
|
||||||
PersistableType(..), sqlNullValue,
|
PersistableType(..), sqlNullValue,
|
||||||
PersistableWidth (..), derivedWidth
|
PersistableWidth (..), derivedWidth,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import GHC.Generics (Generic, Rep, U1 (..), K1 (..), M1 (..), (:*:)(..), to)
|
||||||
import Control.Applicative ((<$>), (<*>), Const (..))
|
import Control.Applicative ((<$>), (<*>), Const (..))
|
||||||
import Data.Monoid (mempty, Sum (..))
|
import Data.Monoid (mempty, Sum (..))
|
||||||
|
|
||||||
@ -48,6 +52,15 @@ unsafePersistableSqlTypeFromNull = PersistableSqlType
|
|||||||
newtype PersistableRecordWidth a =
|
newtype PersistableRecordWidth a =
|
||||||
PersistableRecordWidth { unPRW :: Const (Sum Int) a }
|
PersistableRecordWidth { unPRW :: Const (Sum Int) a }
|
||||||
|
|
||||||
|
-- unsafely map PersistableRecordWidth
|
||||||
|
wmap :: (a -> b) -> PersistableRecordWidth a -> PersistableRecordWidth b
|
||||||
|
f `wmap` prw = PersistableRecordWidth $ f <$> unPRW prw
|
||||||
|
|
||||||
|
-- unsafely ap PersistableRecordWidth
|
||||||
|
wap :: PersistableRecordWidth (a -> b) -> PersistableRecordWidth a -> PersistableRecordWidth b
|
||||||
|
wf `wap` prw = PersistableRecordWidth $ unPRW wf <*> unPRW prw
|
||||||
|
|
||||||
|
|
||||||
-- | Get width 'Int' value of record type 'a'.
|
-- | Get width 'Int' value of record type 'a'.
|
||||||
runPersistableRecordWidth :: PersistableRecordWidth a -> Int
|
runPersistableRecordWidth :: PersistableRecordWidth a -> Int
|
||||||
runPersistableRecordWidth = getSum . getConst . unPRW
|
runPersistableRecordWidth = getSum . getConst . unPRW
|
||||||
@ -66,11 +79,11 @@ unsafeValueWidth = unsafePersistableRecordWidth 1
|
|||||||
|
|
||||||
-- | Derivation rule of 'PersistableRecordWidth' for tuple (,) type.
|
-- | Derivation rule of 'PersistableRecordWidth' for tuple (,) type.
|
||||||
(<&>) :: PersistableRecordWidth a -> PersistableRecordWidth b -> PersistableRecordWidth (a, b)
|
(<&>) :: PersistableRecordWidth a -> PersistableRecordWidth b -> PersistableRecordWidth (a, b)
|
||||||
a <&> b = PersistableRecordWidth $ (,) <$> unPRW a <*> unPRW b
|
a <&> b = (,) `wmap` a `wap` b
|
||||||
|
|
||||||
-- | Derivation rule of 'PersistableRecordWidth' from from Haskell type 'a' into for Haskell type 'Maybe' 'a'.
|
-- | Derivation rule of 'PersistableRecordWidth' from from Haskell type 'a' into for Haskell type 'Maybe' 'a'.
|
||||||
maybeWidth :: PersistableRecordWidth a -> PersistableRecordWidth (Maybe a)
|
maybeWidth :: PersistableRecordWidth a -> PersistableRecordWidth (Maybe a)
|
||||||
maybeWidth = PersistableRecordWidth . (Just <$>) . unPRW
|
maybeWidth = wmap Just
|
||||||
|
|
||||||
-- | Axiom of 'PersistableRecordWidth' for Haskell unit () type.
|
-- | Axiom of 'PersistableRecordWidth' for Haskell unit () type.
|
||||||
voidWidth :: PersistableRecordWidth ()
|
voidWidth :: PersistableRecordWidth ()
|
||||||
@ -90,6 +103,9 @@ sqlNullValue = runPersistableNullValue persistableType
|
|||||||
class PersistableWidth a where
|
class PersistableWidth a where
|
||||||
persistableWidth :: PersistableRecordWidth a
|
persistableWidth :: PersistableRecordWidth a
|
||||||
|
|
||||||
|
default persistableWidth :: (Generic a, GPersistableWidth (Rep a)) => PersistableRecordWidth a
|
||||||
|
persistableWidth = to `wmap` gPersistableWidth
|
||||||
|
|
||||||
-- | Inference rule of 'PersistableRecordWidth' proof object for tuple ('a', 'b') type.
|
-- | Inference rule of 'PersistableRecordWidth' proof object for tuple ('a', 'b') type.
|
||||||
instance (PersistableWidth a, PersistableWidth b) => PersistableWidth (a, b) where
|
instance (PersistableWidth a, PersistableWidth b) => PersistableWidth (a, b) where
|
||||||
persistableWidth = persistableWidth <&> persistableWidth
|
persistableWidth = persistableWidth <&> persistableWidth
|
||||||
@ -106,3 +122,19 @@ instance PersistableWidth () where
|
|||||||
derivedWidth :: PersistableWidth a => (PersistableRecordWidth a, Int)
|
derivedWidth :: PersistableWidth a => (PersistableRecordWidth a, Int)
|
||||||
derivedWidth = (pw, runPersistableRecordWidth pw) where
|
derivedWidth = (pw, runPersistableRecordWidth pw) where
|
||||||
pw = persistableWidth
|
pw = persistableWidth
|
||||||
|
|
||||||
|
|
||||||
|
class GPersistableWidth f where
|
||||||
|
gPersistableWidth :: PersistableRecordWidth (f a)
|
||||||
|
|
||||||
|
instance GPersistableWidth U1 where
|
||||||
|
gPersistableWidth = PersistableRecordWidth $ Const mempty
|
||||||
|
|
||||||
|
instance (GPersistableWidth a, GPersistableWidth b) => GPersistableWidth (a :*: b) where
|
||||||
|
gPersistableWidth = (:*:) `wmap` gPersistableWidth `wap` gPersistableWidth
|
||||||
|
|
||||||
|
instance (GPersistableWidth a) => GPersistableWidth (M1 i c a) where
|
||||||
|
gPersistableWidth = M1 `wmap` gPersistableWidth
|
||||||
|
|
||||||
|
instance PersistableWidth a => GPersistableWidth (K1 i a) where
|
||||||
|
gPersistableWidth = K1 `wmap` persistableWidth
|
||||||
|
Loading…
Reference in New Issue
Block a user