1{-# language FlexibleContexts #-}
2{-# language FlexibleInstances #-}
3{-# language MultiParamTypeClasses #-}
4{-# language StandaloneKindSignatures #-}
5{-# language TypeFamilies #-}
6{-# language UndecidableInstances #-}
8module Rel8.Expr.Function
16import Data.Kind ( Constraint, Type )
20import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
23import Rel8.Expr ( Expr( Expr ) )
24import Rel8.Expr.Opaleye
26 , fromPrimExpr, toPrimExpr, zipPrimExprsWith
28import Rel8.Schema.Nullability ( Nullabilizes )
29import Rel8.Type ( DBType )
32type Function :: Type -> Type -> Constraint
33class Function arg res where
34 applyArgument :: ([Opaleye.PrimExpr] -> Opaleye.PrimExpr) -> arg -> res
37instance (arg ~ Expr a, DBType db, Nullabilizes db b) => Function arg (Expr b)
39 applyArgument f a = castExpr $ fromPrimExpr $ f [toPrimExpr a]
42instance (arg ~ Expr a, Function args res) => Function arg (args -> res) where
43 applyArgument f a = applyArgument (f . (toPrimExpr a :))
46-- | Construct an n-ary function that produces an 'Expr' that when called runs
49-- For example, here's how we can wrap PostgreSQL's @factorial@ function:
52-- factorial :: Expr Int64 -> Expr Data.Scientific.Scientific
53-- factorial = function "factorial"
56-- >>> select c $ pure $ factorial 5
59-- The same approach works for any number of arguments:
62-- power :: Expr Float -> Expr Float -> Expr Double
63-- power = function "power"
66-- >>> select c $ pure $ power 9 3
68function :: Function args result => String -> args -> result
69function = applyArgument . Opaleye.FunExpr
72-- | Construct a function call for functions with no arguments.
74-- For example, we can call the database function @pi()@ by using
78-- sqlPi :: Expr Double
79-- sqlPi = nullaryFunction "pi"
82-- >>> select c $ pure $ sqlPi
84nullaryFunction :: (DBType db, Nullabilizes db a) => String -> Expr a
85nullaryFunction name = castExpr $ Expr (Opaleye.FunExpr name [])
88-- | Construct an expression by applying an infix binary operator to two
90binaryOperator :: (DBType db, Nullabilizes db c)
91 => String -> Expr a -> Expr b -> Expr c
92binaryOperator operator a b =
93 castExpr $ zipPrimExprsWith (Opaleye.BinExpr (Opaleye.OpOther operator)) a b
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list