Use type families instead of empty classes (#220)

* Use type families instead of empty classes

* It's not possible to expand a closed type family.

Co-authored-by: Matt Parsons <parsonsmatt@gmail.com>

Co-authored-by: Matt Parsons <parsonsmatt@gmail.com>
This commit is contained in:
Georgi Lyubenov 2020-10-30 02:04:28 +02:00 committed by GitHub
parent b35713c09f
commit eb91208e94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -220,6 +220,7 @@ import qualified Control.Monad.Trans.Writer as W
#if __GLASGOW_HASKELL__ < 804
import Data.Semigroup
#endif
import Data.Kind (Constraint)
import Data.Proxy (Proxy(..))
import qualified Data.Text.Lazy.Builder as TLB
import Database.Esqueleto.Internal.Internal hiding (From, from, on)
@ -719,15 +720,15 @@ data From a where
-- | Constraint for `on`. Ensures that only types that require an `on` can be used on
-- the left hand side. This was previously reusing the ToFrom class which was actually
-- a bit too lenient as it allowed to much. Expanding this class should not be needed.
-- a bit too lenient as it allowed to much.
--
-- @since 3.4.0.0
class ValidOnClauseValue a where
instance ValidOnClauseValue (From a) where
instance ValidOnClauseValue (SqlQuery a) where
instance ValidOnClauseValue (SqlSetOperation a) where
instance ValidOnClauseValue (a -> SqlQuery b) where
instance {-# OVERLAPPABLE #-} (TypeError ('Text "Illegal use of ON")) => ValidOnClauseValue a where
type family ValidOnClauseValue a :: Constraint where
ValidOnClauseValue (From a) = ()
ValidOnClauseValue (SqlQuery a) = ()
ValidOnClauseValue (SqlSetOperation a) = ()
ValidOnClauseValue (a -> SqlQuery b) = ()
ValidOnClauseValue _ = TypeError ('Text "Illegal use of ON")
-- | An @ON@ clause that describes how two tables are related. This should be
-- used as an infix operator after a 'JOIN'. For example,
@ -772,9 +773,9 @@ type family IsLateral a where
IsLateral (a -> SqlQuery b) = Lateral
IsLateral a = NotLateral
class ErrorOnLateral a where
instance (TypeError ('Text "LATERAL can only be used for INNER, LEFT, and CROSS join kinds.")) => ErrorOnLateral (a -> SqlQuery b) where
instance {-# OVERLAPPABLE #-} ErrorOnLateral a where
type family ErrorOnLateral a :: Constraint where
ErrorOnLateral (a -> SqlQuery b) = TypeError ('Text "LATERAL can only be used for INNER, LEFT, and CROSS join kinds.")
ErrorOnLateral _ = ()
{-- Type class magic to allow the use of the `InnerJoin` family of data constructors in from --}
class ToFrom a where