Skip to content

Instantly share code, notes, and snippets.

@aaronlevin
Last active August 29, 2015 14:13
Show Gist options
  • Select an option

  • Save aaronlevin/61101a3bfe6e3190e573 to your computer and use it in GitHub Desktop.

Select an option

Save aaronlevin/61101a3bfe6e3190e573 to your computer and use it in GitHub Desktop.
Sql Servant
-- | playing around with a possible postgresql-simple plugin for servant
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Galene.Common.Update where
import Data.Proxy (Proxy(Proxy))
import GHC.TypeLits (KnownSymbol, Symbol)
data Field (f :: Symbol) (t :: *) = Field
data Update (t :: Symbol) (d :: *) = Update
data (path :: k) :> a = Proxy path :> a
infixr 9 :>
-- | in the real verison `Show` would be replaced with `ToRow`
data SqlQuery where
SqlQuery :: (Show a) => [a] -> SqlQuery
class HasSQL fields where
type Query fields :: *
update :: Proxy fields -> Query fields -> IO ()
instance KnownSymbol t => HasSQL (Update t result) where
type Query (Update t result) = SqlQuery
update _ _ = putStrLn "testing"
instance (HasSQL sub, Show t) => HasSQL (Field c t :> sub) where
type Query (Field sym t :> sub) = t -> Query sub
update _ _ = putStrLn "testing"
-- | user code
data Product = Product Int String
type MyUpdate = Field "id" Int :> Update "product" Product
f :: Int -> SqlQuery
f i = SqlQuery [i]
myQuery :: Query MyUpdate
myQuery = f
query :: HasSQL fields => Proxy fields -> Query fields -> IO ()
query = update
x :: IO ()
x = query (Proxy :: Proxy MyUpdate) myQuery
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment