{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
#if MIN_VERSION_ghc(9,0,0)
{-# LANGUAGE StandaloneKindSignatures #-}
#endif
module GHC.TcPlugin.API.Names
( ResolveNames, resolveNames
, Wear, QualifiedName(..), NameResolution(..)
, Promoted
, Lookupable(..)
, Generically1(..)
) where
import Prelude
hiding ( lookup )
import Data.Coerce
( Coercible, coerce )
import Data.Kind
( Type, Constraint )
import GHC.Generics
( Generic(..)
#if MIN_VERSION_base(4,17,0)
, Generically1(..)
#endif
, (:+:)(..), (:*:)(..)
, K1(K1), M1(M1), U1(..), V1, Rec0
)
import GHC.TypeLits
( TypeError, ErrorMessage(..) )
import Data.Map
( Map )
import qualified Data.Map as Map
import Control.Monad.Trans.State.Strict
( StateT, evalStateT, get, modify )
import Control.Monad.Trans.Class
( MonadTrans(lift) )
#if MIN_VERSION_ghc(9,8,0)
import GHC.Iface.Errors.Ppr
( missingInterfaceErrorDiagnostic )
#endif
#if MIN_VERSION_ghc(9,3,0)
import GHC.Iface.Errors
( cannotFindModule )
#elif MIN_VERSION_ghc(9,2,0)
import GHC.Iface.Load
( cannotFindModule )
#else
import GHC.Driver.Types
( hsc_dflags )
import GHC.Driver.Finder
( cannotFindModule )
#endif
#if MIN_VERSION_ghc(9,5,0)
import Language.Haskell.Syntax.Module.Name
( moduleNameString )
#else
import GHC.Unit.Module.Name
( moduleNameString )
#endif
import GHC.Utils.Panic
( pgmErrorDoc )
import GHC.Tc.Plugin
( getTopEnv )
#if MIN_VERSION_ghc(9,8,0)
import GHC.Types.Error
( HasDefaultDiagnosticOpts(defaultOpts) )
#endif
import GHC.TcPlugin.API
hiding ( Type )
import GHC.TcPlugin.API.Internal
( MonadTcPlugin(liftTcPluginM) )
data QualifiedName (thing :: Type)
= Qualified
{
forall thing. QualifiedName thing -> String
name :: String
, forall thing. QualifiedName thing -> ModuleName
module' :: ModuleName
, forall thing. QualifiedName thing -> PkgQual
package :: PkgQual
}
data NameResolution = Named | Resolved
data Promoted (thing :: k) :: Type
#if MIN_VERSION_ghc(9,0,0)
type Wear :: forall k. NameResolution -> k -> Type
#endif
type family Wear (n :: NameResolution) (thing :: k) :: Type where
#if MIN_VERSION_ghc(9,0,0)
Wear @Type Named thing = QualifiedName thing
#else
Wear Named thing = QualifiedName thing
#endif
Wear Resolved (Promoted DataCon) = TyCon
Wear Resolved (Promoted a)
= TypeError
( Text "Cannot promote " :<>: ShowType a :<>: Text "."
:$$: Text "Can only promote 'DataCon's."
)
Wear Resolved thing = thing
type family UnwearNamed (loc :: Type) :: Type where
UnwearNamed (QualifiedName thing) = thing
#if MIN_VERSION_ghc(9,0,0)
type Lookupable :: forall {k}. k -> Constraint
#endif
class Lookupable (a :: k) where
mkOccName :: String -> OccName
lookup :: MonadTcPlugin m => Name -> m (Wear Resolved a)
instance Lookupable TyCon where
mkOccName :: String -> OccName
mkOccName = String -> OccName
mkTcOcc
lookup :: forall (m :: * -> *).
MonadTcPlugin m =>
Name -> m (Wear 'Resolved TyCon)
lookup = Name -> m TyCon
Name -> m (Wear 'Resolved TyCon)
forall (m :: * -> *). MonadTcPlugin m => Name -> m TyCon
tcLookupTyCon
instance Lookupable DataCon where
mkOccName :: String -> OccName
mkOccName = String -> OccName
mkDataOcc
lookup :: forall (m :: * -> *).
MonadTcPlugin m =>
Name -> m (Wear 'Resolved DataCon)
lookup = Name -> m DataCon
Name -> m (Wear 'Resolved DataCon)
forall (m :: * -> *). MonadTcPlugin m => Name -> m DataCon
tcLookupDataCon
instance Lookupable Class where
mkOccName :: String -> OccName
mkOccName = String -> OccName
mkClsOcc
lookup :: forall (m :: * -> *).
MonadTcPlugin m =>
Name -> m (Wear 'Resolved Class)
lookup = Name -> m Class
Name -> m (Wear 'Resolved Class)
forall (m :: * -> *). MonadTcPlugin m => Name -> m Class
tcLookupClass
instance Lookupable (Promoted DataCon) where
mkOccName :: String -> OccName
mkOccName = String -> OccName
mkDataOcc
lookup :: forall (m :: * -> *).
MonadTcPlugin m =>
Name -> m (Wear 'Resolved (Promoted DataCon))
lookup = (DataCon -> TyCon) -> m DataCon -> m TyCon
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DataCon -> TyCon
promoteDataCon (m DataCon -> m TyCon) -> (Name -> m DataCon) -> Name -> m TyCon
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> m DataCon
forall (m :: * -> *). MonadTcPlugin m => Name -> m DataCon
tcLookupDataCon
class ResolveNames (f :: NameResolution -> Type) where
resolve_names :: ( Coercible res ( f Resolved ), MonadTcPlugin m )
=> f Named -> m res
resolveNames :: ( MonadTcPlugin m, ResolveNames f )
=> f Named -> m ( f Resolved )
resolveNames :: forall (m :: * -> *) (f :: NameResolution -> *).
(MonadTcPlugin m, ResolveNames f) =>
f 'Named -> m (f 'Resolved)
resolveNames = f 'Named -> m (f 'Resolved)
forall res (m :: * -> *).
(Coercible res (f 'Resolved), MonadTcPlugin m) =>
f 'Named -> m res
forall (f :: NameResolution -> *) res (m :: * -> *).
(ResolveNames f, Coercible res (f 'Resolved), MonadTcPlugin m) =>
f 'Named -> m res
resolve_names
instance ( Generic (f Named)
, Generic (f Resolved)
, GTraversableC ResolveName (Rep (f Named)) (Rep (f Resolved))
)
=> ResolveNames (Generically1 f) where
resolve_names
:: forall
#if MIN_VERSION_ghc(9,0,0)
{m}
#else
m
#endif
res
. ( Coercible res ( Generically1 f Resolved ), MonadTcPlugin m )
=> Generically1 f Named -> m res
resolve_names :: forall {m :: * -> *} res.
(Coercible res (Generically1 f 'Resolved), MonadTcPlugin m) =>
Generically1 f 'Named -> m res
resolve_names ( Generically1 f 'Named
dat )
= ( StateT ImportedModules m res -> ImportedModules -> m res
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
`evalStateT` ImportedModules
emptyModules )
(StateT ImportedModules m res -> m res)
-> StateT ImportedModules m res -> m res
forall a b. (a -> b) -> a -> b
$ f 'Resolved -> res
forall a b. Coercible a b => a -> b
coerce (f 'Resolved -> res)
-> (Rep (f 'Resolved) Any -> f 'Resolved)
-> Rep (f 'Resolved) Any
-> res
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a x. Generic a => Rep a x -> a
to @(f Resolved)
(Rep (f 'Resolved) Any -> res)
-> StateT ImportedModules m (Rep (f 'Resolved) Any)
-> StateT ImportedModules m res
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (c :: * -> * -> Constraint) (s :: * -> *) (t :: * -> *) x.
GTraversableC c s t =>
TraversalC c (s x) (t x)
gtraverseC @ResolveName a -> StateT ImportedModules m b
Wear 'Named (UnwearNamed a)
-> StateT ImportedModules m (Wear 'Resolved (UnwearNamed a))
forall a b. ResolveName a b => a -> StateT ImportedModules m b
forall thing (m :: * -> *).
(ResolveName (Wear 'Named thing) (Wear 'Resolved thing),
MonadTcPlugin m) =>
Wear 'Named thing
-> StateT ImportedModules m (Wear 'Resolved thing)
resolveName ( f 'Named -> Rep (f 'Named) Any
forall x. f 'Named -> Rep (f 'Named) x
forall a x. Generic a => a -> Rep a x
from f 'Named
dat )
class ( a ~ Wear Named ( UnwearNamed a )
, b ~ Wear Resolved ( UnwearNamed a )
, Lookupable ( UnwearNamed a )
)
=> ResolveName (a :: Type) (b :: Type)
instance ( a ~ Wear Named ( UnwearNamed a )
, b ~ Wear Resolved ( UnwearNamed a )
, Lookupable ( UnwearNamed a )
)
=> ResolveName a b
resolveName :: forall (thing :: Type) m
. ResolveName ( Wear Named thing ) ( Wear Resolved thing )
=> MonadTcPlugin m
=> Wear Named thing
-> StateT ImportedModules m ( Wear Resolved thing )
resolveName :: forall thing (m :: * -> *).
(ResolveName (Wear 'Named thing) (Wear 'Resolved thing),
MonadTcPlugin m) =>
Wear 'Named thing
-> StateT ImportedModules m (Wear 'Resolved thing)
resolveName (Qualified String
str ModuleName
mod_name PkgQual
pkg) = do
Module
md <- PkgQual -> ModuleName -> StateT ImportedModules m Module
forall (m :: * -> *).
MonadTcPlugin m =>
PkgQual -> ModuleName -> StateT ImportedModules m Module
lookupModule PkgQual
pkg ModuleName
mod_name
Name
nm <- m Name -> StateT ImportedModules m Name
forall (m :: * -> *) a.
Monad m =>
m a -> StateT ImportedModules m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Name -> StateT ImportedModules m Name)
-> m Name -> StateT ImportedModules m Name
forall a b. (a -> b) -> a -> b
$ Module -> OccName -> m Name
forall (m :: * -> *).
MonadTcPlugin m =>
Module -> OccName -> m Name
lookupOrig Module
md
(forall a. Lookupable a => String -> OccName
forall {k} (a :: k). Lookupable a => String -> OccName
mkOccName
#if !MIN_VERSION_ghc(9,0,0)
@_
#endif
@thing
String
str
)
m (Wear 'Resolved thing)
-> StateT ImportedModules m (Wear 'Resolved thing)
forall (m :: * -> *) a.
Monad m =>
m a -> StateT ImportedModules m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Wear 'Resolved thing)
-> StateT ImportedModules m (Wear 'Resolved thing))
-> m (Wear 'Resolved thing)
-> StateT ImportedModules m (Wear 'Resolved thing)
forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *).
(Lookupable a, MonadTcPlugin m) =>
Name -> m (Wear 'Resolved a)
forall {k} (a :: k) (m :: * -> *).
(Lookupable a, MonadTcPlugin m) =>
Name -> m (Wear 'Resolved a)
lookup
#if !MIN_VERSION_ghc(9,0,0)
@_
#endif
@thing Name
nm
newtype ImportedModules
= ImportedModules
{ ImportedModules -> Map (PkgQual, ModuleName) Module
imported_modules :: Map (PkgQual, ModuleName) Module
}
emptyModules :: ImportedModules
emptyModules :: ImportedModules
emptyModules =
Map (PkgQual, ModuleName) Module -> ImportedModules
ImportedModules Map (PkgQual, ModuleName) Module
forall k a. Map k a
Map.empty
lookupCachedModule :: Monad m => PkgQual -> ModuleName -> StateT ImportedModules m (Maybe Module)
lookupCachedModule :: forall (m :: * -> *).
Monad m =>
PkgQual -> ModuleName -> StateT ImportedModules m (Maybe Module)
lookupCachedModule PkgQual
pkg ModuleName
modl = (PkgQual, ModuleName)
-> Map (PkgQual, ModuleName) Module -> Maybe Module
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (PkgQual
pkg, ModuleName
modl) (Map (PkgQual, ModuleName) Module -> Maybe Module)
-> (ImportedModules -> Map (PkgQual, ModuleName) Module)
-> ImportedModules
-> Maybe Module
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ImportedModules -> Map (PkgQual, ModuleName) Module
imported_modules (ImportedModules -> Maybe Module)
-> StateT ImportedModules m ImportedModules
-> StateT ImportedModules m (Maybe Module)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT ImportedModules m ImportedModules
forall (m :: * -> *) s. Monad m => StateT s m s
get
insertCachedModule :: Monad m => PkgQual -> ModuleName -> Module -> StateT ImportedModules m ()
insertCachedModule :: forall (m :: * -> *).
Monad m =>
PkgQual -> ModuleName -> Module -> StateT ImportedModules m ()
insertCachedModule PkgQual
pkg ModuleName
modl Module
md = (ImportedModules -> ImportedModules) -> StateT ImportedModules m ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify ((ImportedModules -> ImportedModules)
-> StateT ImportedModules m ())
-> (ImportedModules -> ImportedModules)
-> StateT ImportedModules m ()
forall a b. (a -> b) -> a -> b
$ \ImportedModules
mods ->
ImportedModules
mods{ imported_modules = Map.insert (pkg, modl) md (imported_modules mods) }
lookupModule :: MonadTcPlugin m => PkgQual -> ModuleName -> StateT ImportedModules m Module
lookupModule :: forall (m :: * -> *).
MonadTcPlugin m =>
PkgQual -> ModuleName -> StateT ImportedModules m Module
lookupModule PkgQual
pkg ModuleName
mod_name = do
Maybe Module
cachedResult <- PkgQual -> ModuleName -> StateT ImportedModules m (Maybe Module)
forall (m :: * -> *).
Monad m =>
PkgQual -> ModuleName -> StateT ImportedModules m (Maybe Module)
lookupCachedModule PkgQual
pkg ModuleName
mod_name
case Maybe Module
cachedResult of
Just Module
res -> do
PkgQual -> ModuleName -> Module -> StateT ImportedModules m ()
forall (m :: * -> *).
Monad m =>
PkgQual -> ModuleName -> Module -> StateT ImportedModules m ()
insertCachedModule PkgQual
pkg ModuleName
mod_name Module
res
Module -> StateT ImportedModules m Module
forall a. a -> StateT ImportedModules m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Module
res
Maybe Module
Nothing -> do
FindResult
findResult <- m FindResult -> StateT ImportedModules m FindResult
forall (m :: * -> *) a.
Monad m =>
m a -> StateT ImportedModules m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m FindResult -> StateT ImportedModules m FindResult)
-> m FindResult -> StateT ImportedModules m FindResult
forall a b. (a -> b) -> a -> b
$ ModuleName -> PkgQual -> m FindResult
forall (m :: * -> *).
MonadTcPlugin m =>
ModuleName -> PkgQual -> m FindResult
findImportedModule ModuleName
mod_name PkgQual
pkg
case FindResult
findResult of
Found ModLocation
_ Module
res
-> Module -> StateT ImportedModules m Module
forall a. a -> StateT ImportedModules m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Module
res
FindResult
other -> do
HscEnv
hsc_env <- m HscEnv -> StateT ImportedModules m HscEnv
forall (m :: * -> *) a.
Monad m =>
m a -> StateT ImportedModules m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m HscEnv -> StateT ImportedModules m HscEnv)
-> (TcPluginM HscEnv -> m HscEnv)
-> TcPluginM HscEnv
-> StateT ImportedModules m HscEnv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcPluginM HscEnv -> m HscEnv
forall a. TcPluginM a -> m a
forall (m :: * -> *) a. MonadTcPlugin m => TcPluginM a -> m a
liftTcPluginM (TcPluginM HscEnv -> StateT ImportedModules m HscEnv)
-> TcPluginM HscEnv -> StateT ImportedModules m HscEnv
forall a b. (a -> b) -> a -> b
$ TcPluginM HscEnv
getTopEnv
let
err_doc :: SDoc
err_doc :: SDoc
err_doc =
#if MIN_VERSION_ghc(9,8,0)
missingInterfaceErrorDiagnostic defaultOpts $
#endif
#if MIN_VERSION_ghc(9,2,0)
HscEnv -> ModuleName -> FindResult -> SDoc
cannotFindModule HscEnv
hsc_env ModuleName
mod_name FindResult
other
#else
cannotFindModule (hsc_dflags hsc_env) mod_name other
#endif
String -> SDoc -> StateT ImportedModules m Module
forall a. String -> SDoc -> a
pgmErrorDoc
( String
"GHC.TcPlugin.API: could not find module "
String -> String -> String
forall a. Semigroup a => a -> a -> a
<> ModuleName -> String
moduleNameString ModuleName
mod_name
String -> String -> String
forall a. Semigroup a => a -> a -> a
<> case PkgQual -> Maybe String
pkgQualToPkgName PkgQual
pkg of
Just String
p -> String
" in package " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
p
Maybe String
Nothing -> String
forall a. Monoid a => a
mempty
)
SDoc
err_doc
type TraversalC (c :: Type -> Type -> Constraint) (s :: Type) (t :: Type)
= forall f. ( Applicative f )
=> ( forall a b. c a b => a -> f b ) -> s -> f t
class GTraversableC (c :: Type -> Type -> Constraint) (s :: Type -> Type) (t :: Type -> Type) where
gtraverseC :: TraversalC c (s x) (t x)
instance
( GTraversableC c l l'
, GTraversableC c r r'
) => GTraversableC c (l :*: r) (l' :*: r') where
gtraverseC :: forall x. TraversalC c ((:*:) l r x) ((:*:) l' r' x)
gtraverseC forall a b. c a b => a -> f b
f (l x
l :*: r x
r)
= l' x -> r' x -> (:*:) l' r' x
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:) (l' x -> r' x -> (:*:) l' r' x)
-> f (l' x) -> f (r' x -> (:*:) l' r' x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (c :: * -> * -> Constraint) (s :: * -> *) (t :: * -> *) x.
GTraversableC c s t =>
TraversalC c (s x) (t x)
gtraverseC @c a -> f b
forall a b. c a b => a -> f b
f l x
l f (r' x -> (:*:) l' r' x) -> f (r' x) -> f ((:*:) l' r' x)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (c :: * -> * -> Constraint) (s :: * -> *) (t :: * -> *) x.
GTraversableC c s t =>
TraversalC c (s x) (t x)
gtraverseC @c a -> f b
forall a b. c a b => a -> f b
f r x
r
instance
( GTraversableC c l l'
, GTraversableC c r r'
) => GTraversableC c (l :+: r) (l' :+: r') where
gtraverseC :: forall x. TraversalC c ((:+:) l r x) ((:+:) l' r' x)
gtraverseC forall a b. c a b => a -> f b
f (L1 l x
l) = l' x -> (:+:) l' r' x
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 (l' x -> (:+:) l' r' x) -> f (l' x) -> f ((:+:) l' r' x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (c :: * -> * -> Constraint) (s :: * -> *) (t :: * -> *) x.
GTraversableC c s t =>
TraversalC c (s x) (t x)
gtraverseC @c a -> f b
forall a b. c a b => a -> f b
f l x
l
gtraverseC forall a b. c a b => a -> f b
f (R1 r x
r) = r' x -> (:+:) l' r' x
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 (r' x -> (:+:) l' r' x) -> f (r' x) -> f ((:+:) l' r' x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (c :: * -> * -> Constraint) (s :: * -> *) (t :: * -> *) x.
GTraversableC c s t =>
TraversalC c (s x) (t x)
gtraverseC @c a -> f b
forall a b. c a b => a -> f b
f r x
r
instance GTraversableC c s t
=> GTraversableC c (M1 i m s) (M1 i m t) where
gtraverseC :: forall x. TraversalC c (M1 i m s x) (M1 i m t x)
gtraverseC forall a b. c a b => a -> f b
f (M1 s x
x) = t x -> M1 i m t x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (t x -> M1 i m t x) -> f (t x) -> f (M1 i m t x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (c :: * -> * -> Constraint) (s :: * -> *) (t :: * -> *) x.
GTraversableC c s t =>
TraversalC c (s x) (t x)
gtraverseC @c a -> f b
forall a b. c a b => a -> f b
f s x
x
instance GTraversableC c U1 U1 where
gtraverseC :: forall x. TraversalC c (U1 x) (U1 x)
gtraverseC forall a b. c a b => a -> f b
_ U1 x
_ = U1 x -> f (U1 x)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure U1 x
forall k (p :: k). U1 p
U1
instance GTraversableC c V1 V1 where
gtraverseC :: forall x. TraversalC c (V1 x) (V1 x)
gtraverseC forall a b. c a b => a -> f b
_ = V1 x -> f (V1 x)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
instance c a b => GTraversableC c (Rec0 a) (Rec0 b) where
gtraverseC :: forall x. TraversalC c (Rec0 a x) (Rec0 b x)
gtraverseC forall a b. c a b => a -> f b
f (K1 a
a) = b -> K1 R b x
forall k i c (p :: k). c -> K1 i c p
K1 (b -> K1 R b x) -> f b -> f (K1 R b x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
forall a b. c a b => a -> f b
f a
a
#if !MIN_VERSION_base(4,17,0)
newtype Generically1 (f :: k -> Type) (a :: k) = Generically1 ( f a )
#endif