on 134ddcf help sign in
rel8/src/Rel8/Type/Array1D.hs
135 lines 3.8 kB history raw
1{-# language DataKinds #-}
2{-# language DeriveTraversable #-}
3{-# language DerivingStrategies #-}
4{-# language GeneralizedNewtypeDeriving #-}
5{-# language NamedFieldPuns #-}
6{-# language StandaloneKindSignatures #-}
7{-# language TypeFamilies #-}
8{-# language UndecidableInstances #-}
10{-# options_ghc -fno-warn-redundant-constraints #-}
12module Rel8.Type.Array1D
13 ( Array1D( Array1D )
14 , getArray1D
15 )
16where
18-- aeson
19import Data.Aeson
20 ( ToJSON
21 , ToJSON1
22 , ToJSONKey
23 , FromJSON
24 , FromJSON1
25 , FromJSONKey
26 )
28-- base
29import Control.Applicative ( Alternative, (<|>) )
30import Control.Monad ( MonadPlus )
31import Data.Functor.Classes ( Eq1, Ord1, Read1, Show1 )
32import Data.Kind ( Type )
33import GHC.Exts ( IsList )
34import Prelude hiding ( null )
36-- hasql
37import qualified Hasql.Decoders as Hasql
39-- opaleye
40import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
42-- rel8
43import Rel8.Expr.Opaleye ( zipPrimExprsWith )
44import Rel8.Expr.Serialize ( litExpr )
45import Rel8.Schema.Nullability
46 ( Nullability( Nullable, NonNullable )
47 , Nullabilizes, nullabilization
48 )
49import Rel8.Type ( DBType, typeInformation )
50import Rel8.Type.Eq ( DBEq )
51import Rel8.Type.Information ( TypeInformation(..) )
52import Rel8.Type.Monoid ( DBMonoid, memptyExpr )
53import Rel8.Type.Ord ( DBMax, DBMin, DBOrd )
54import Rel8.Type.Semigroup ( DBSemigroup, (<>.) )
56-- semigroupoids
57import Data.Functor.Alt ( Alt, (<!>) )
58import Data.Functor.Apply ( Apply )
59import Data.Functor.Bind ( Bind )
60import Data.Functor.Plus ( Plus )
62-- semialign
63import Data.Align ( Align )
64import Data.Semialign ( Semialign )
65import Data.Zip ( Repeat, Unzip, Zip )
68newtype Array1D a = Array1D [a]
69 deriving stock Traversable
70 deriving newtype
71 ( Eq, Ord, Read, Show, Semigroup, Monoid, IsList
72 , Functor, Foldable
73 , Eq1, Ord1, Read1, Show1
74 , FromJSON1, ToJSON1, FromJSON, FromJSONKey, ToJSON, ToJSONKey
75 , Apply, Applicative, Alternative, Plus, Bind, Monad, MonadPlus
76 , Align, Semialign, Repeat, Unzip, Zip
77 )
80instance Alt Array1D where
81 (<!>) = (<|>)
84getArray1D :: Array1D a -> [a]
85getArray1D (Array1D a) = a
88type IsArray1D :: Type -> Bool
89type family IsArray1D a where
90 IsArray1D (Array1D _) = 'True
91 IsArray1D _ = 'False
94array1DTypeInformation :: IsArray1D db ~ 'False
95 => Nullability db a
96 -> TypeInformation db
97 -> TypeInformation (Array1D a)
98array1DTypeInformation nullability info =
99 case info of
100 TypeInformation{ encode, decode, typeName, out } -> TypeInformation
101 { decode = case nullability of
102 Nullable -> Array1D <$> Hasql.listArray (Hasql.nullable (out <$> decode))
103 NonNullable -> Array1D <$> Hasql.listArray (Hasql.nonNullable (out <$> decode))
104 , encode = case nullability of
105 Nullable -> Opaleye.ArrayExpr . fmap (maybe null encode) . getArray1D
106 NonNullable -> Opaleye.ArrayExpr . fmap encode . getArray1D
107 , typeName = typeName <> "[]"
108 , out = id
109 }
110 where
111 null = Opaleye.ConstExpr Opaleye.NullLit
114instance (DBType db, Nullabilizes db a, IsArray1D db ~ 'False) => DBType (Array1D a) where
115 typeInformation = array1DTypeInformation nullabilization typeInformation
118instance (DBEq db, Nullabilizes db a, IsArray1D db ~ 'False) => DBEq (Array1D a)
121instance (DBOrd db, Nullabilizes db a, IsArray1D db ~ 'False) => DBOrd (Array1D a)
124instance (DBMax db, Nullabilizes db a, IsArray1D db ~ 'False) => DBMax (Array1D a)
127instance (DBMin db, Nullabilizes db a, IsArray1D db ~ 'False) => DBMin (Array1D a)
130instance (DBType db, Nullabilizes db a, IsArray1D db ~ 'False) => DBSemigroup (Array1D a) where
131 (<>.) = zipPrimExprsWith (Opaleye.BinExpr (Opaleye.:||))
134instance (DBType db, Nullabilizes db a, IsArray1D db ~ 'False) => DBMonoid (Array1D a) where
135 memptyExpr = litExpr mempty