64 lines
2.2 KiB
Haskell
64 lines
2.2 KiB
Haskell
{-# LANGUAGE CPP #-}
|
|
{-# LANGUAGE ConstraintKinds #-}
|
|
{-# LANGUAGE DataKinds #-}
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
{-# LANGUAGE FlexibleInstances #-}
|
|
{-# LANGUAGE GADTs #-}
|
|
{-# LANGUAGE InstanceSigs #-}
|
|
{-# LANGUAGE KindSignatures #-}
|
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
|
{-# LANGUAGE PolyKinds #-}
|
|
{-# LANGUAGE RankNTypes #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
{-# LANGUAGE TypeFamilies #-}
|
|
{-# LANGUAGE TypeOperators #-}
|
|
{-# LANGUAGE UndecidableInstances #-}
|
|
#if __GLASGOW_HASKELL__ >= 800
|
|
{-# LANGUAGE UndecidableSuperClasses #-}
|
|
#endif
|
|
module Servant.Swagger.Internal.TypeLevel.Every where
|
|
|
|
import Data.Proxy
|
|
import GHC.Exts (Constraint)
|
|
|
|
import Servant.Swagger.Internal.TypeLevel.TMap
|
|
|
|
-- $setup
|
|
-- >>> :set -XDataKinds
|
|
-- >>> :set -XFlexibleContexts
|
|
-- >>> :set -XGADTs
|
|
-- >>> :set -XRankNTypes
|
|
-- >>> :set -XScopedTypeVariables
|
|
-- >>> import GHC.TypeLits
|
|
-- >>> import Data.List
|
|
|
|
-- | Apply multiple constraint constructors to a type.
|
|
--
|
|
-- @
|
|
-- EveryTF '[Show, Read] a ~ (Show a, Read a)
|
|
-- @
|
|
--
|
|
-- Note that since this is a type family, you have to alway fully apply @'EveryTF'@.
|
|
--
|
|
-- For partial application of multiple constraint constructors see @'Every'@.
|
|
type family EveryTF cs x :: Constraint where
|
|
EveryTF '[] x = ()
|
|
EveryTF (c ': cs) x = (c x, EveryTF cs x)
|
|
|
|
-- | Apply multiple constraint constructors to a type as a class.
|
|
--
|
|
-- This is different from @'EveryTF'@ in that it allows partial application.
|
|
class EveryTF cs x => Every (cs :: [* -> Constraint]) (x :: *) where
|
|
|
|
instance Every '[] x where
|
|
instance (c x, Every cs x) => Every (c ': cs) x where
|
|
|
|
-- | Like @'tmap'@, but uses @'Every'@ for multiple constraints.
|
|
--
|
|
-- >>> let zero :: forall p a. (Show a, Num a) => p a -> String; zero _ = show (0 :: a)
|
|
-- >>> tmapEvery (Proxy :: Proxy [Show, Num]) zero (Proxy :: Proxy [Int, Float]) :: [String]
|
|
-- ["0","0.0"]
|
|
tmapEvery :: forall a cs p p'' xs. (TMap (Every cs) xs) =>
|
|
p cs -> (forall x p'. Every cs x => p' x -> a) -> p'' xs -> [a]
|
|
tmapEvery _ = tmap (Proxy :: Proxy (Every cs))
|