ghc-exactprint-0.5.3.1: tests/examples/ghc80/dynamic-paper.hs
{- This is the code extracted from "A reflection on types", by Simon PJ,
Stephanie Weirich, Richard Eisenberg, and Dimitrios Vytiniotis, 2016. -}
{-# LANGUAGE RankNTypes, PolyKinds, TypeOperators,
ScopedTypeVariables, GADTs, FlexibleInstances,
UndecidableInstances, RebindableSyntax,
DataKinds, MagicHash, AutoDeriveTypeable, TypeInType #-}
{-# OPTIONS_GHC -fno-warn-missing-methods -fno-warn-redundant-constraints #-}
module Dynamic where
import Data.Map ( Map )
import qualified Data.Map as Map
import Unsafe.Coerce ( unsafeCoerce )
import Control.Monad ( (<=<) )
import Prelude hiding ( lookup, fromInteger, replicate )
import qualified Prelude
import qualified Data.Typeable
import qualified Data.Data
import Data.Kind
lookupMap = Map.lookup
insertMap = Map.insert
-- let's ignore overloaded numbers
fromInteger :: Integer -> Int
fromInteger = Prelude.fromInteger
insertStore = undefined
schema = undefined
withTypeable = undefined
throw# = undefined
toDynamicST = undefined
fromDynamicST = undefined
extendStore :: Typeable a => STRef s a -> a -> Store -> Store
lookupStore :: Typeable a => STRef s a -> Store -> Maybe a
type Key = Int
data STRef s a = STR Key
type Store = Map Key Dynamic
extendStore (STR k) v s = insertMap k (toDynamicST v) s
lookupStore (STR k) s = case lookupMap k s of
Just d -> fromDynamicST d
Nothing -> Nothing
toDynamicST :: Typeable a => a -> Dynamic
fromDynamicST :: Typeable a => Dynamic -> Maybe a
eval = undefined
data Term
data DynamicSilly = DIntSilly Int
| DBoolSilly Bool
| DCharSilly Char
| DPairSilly DynamicSilly DynamicSilly
toDynInt :: Int -> DynamicSilly
toDynInt = DIntSilly
fromDynInt :: DynamicSilly -> Maybe Int
fromDynInt (DIntSilly n) = Just n
fromDynInt _ = Nothing
toDynPair :: DynamicSilly -> DynamicSilly -> DynamicSilly
toDynPair = DPairSilly
dynFstSilly :: DynamicSilly -> Maybe DynamicSilly
dynFstSilly (DPairSilly x1 x2) = Just x1
dynFstSilly _ = Nothing
eval :: Term -> DynamicSilly
eqT = undefined
instance Typeable (->)
instance Typeable Maybe
instance Typeable Bool
instance Typeable Int
instance (Typeable a, Typeable b) => Typeable (a b)
instance Typeable (,)
instance Eq TypeRepX
data Dynamic where
Dyn :: TypeRep a -> a -> Dynamic
toDynamic :: Typeable a => a -> Dynamic
toDynamic x = Dyn typeRep x
eqTNoKind = undefined
eqTNoKind :: TypeRep a -> TypeRep b -> Maybe (a :***: b)
-- Primitive; implemented by compiler
data a :***: b where
ReflNoKind :: a :***: a
fromDynamic :: forall d. Typeable d => Dynamic -> Maybe d
fromDynamic (Dyn (ra :: TypeRep a) (x :: a))
= case eqT ra (typeRep :: TypeRep d) of
Nothing -> Nothing
Just Refl -> Just x
fromDynamicMonad :: forall d. Typeable d => Dynamic -> Maybe d
fromDynamicMonad (Dyn ra x)
= do Refl <- eqT ra (typeRep :: TypeRep d)
return x
cast :: forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast x = do Refl <- eqT (typeRep :: TypeRep a)
(typeRep :: TypeRep b)
return x
gcast :: forall a b c. (Typeable a, Typeable b) => c a -> Maybe (c b)
gcast x = do Refl <- eqT (typeRep :: TypeRep a)
(typeRep :: TypeRep b)
return x
data SameKind :: k -> k -> *
type CheckAppResult = SameKind AppResult AppResultNoKind
-- not the most thorough check
foo :: AppResult x -> AppResultNoKind x
foo (App y z) = AppNoKind y z
splitApp :: TypeRep a -> Maybe (AppResult a)
splitApp = undefined
splitAppNoKind = undefined
splitAppNoKind :: TypeRep a -> Maybe (AppResultNoKind a)
-- Primitive; implemented by compiler
data AppResultNoKind t where
AppNoKind :: TypeRep a -> TypeRep b -> AppResultNoKind (a b)
dynFstNoKind :: Dynamic -> Maybe Dynamic
dynFstNoKind (Dyn rpab x)
= do AppNoKind rpa rb <- splitAppNoKind rpab
AppNoKind rp ra <- splitAppNoKind rpa
Refl <- eqT rp (typeRep :: TypeRep (,))
return (Dyn ra (fst x))
dynApply :: Dynamic -> Dynamic -> Maybe Dynamic
dynApply (Dyn rf f) (Dyn rx x) = do
App ra rt2 <- splitApp rf
App rtc rt1 <- splitApp ra
Refl <- eqT rtc (typeRep :: TypeRep (->))
Refl <- eqT rt1 rx
return (Dyn rt2 (f x))
data TypeRepAbstract (a :: k) -- primitive, indexed by type and kind
class Typeable (a :: k) where
typeRep :: TypeRep a
data AppResult (t :: k) where
App :: forall k1 k (a :: k1 -> k) (b :: k1).
TypeRep a -> TypeRep b -> AppResult (a b)
dynFst :: Dynamic -> Maybe Dynamic
dynFst (Dyn (rpab :: TypeRep pab) (x :: pab))
= do App (rpa :: TypeRep pa ) (rb :: TypeRep b) <- splitApp rpab
-- introduces kind |k2|, and types |pa :: k2 -> *|, |b :: k2|
App (rp :: TypeRep p ) (ra :: TypeRep a) <- splitApp rpa
-- introduces kind |k1|, and types |p :: k1 -> k2 -> *|, |a :: k1|
Refl <- eqT rp (typeRep :: TypeRep (,))
-- introduces |p ~ (,)| and |(k1 -> k2 -> *) ~ (* -> * -> *)|
return (Dyn ra (fst x))
eqT :: forall k1 k2 (a :: k1) (b :: k2). TypeRep a -> TypeRep b -> Maybe (a :~: b)
data (a :: k1) :~: (b :: k2) where
Refl :: forall k (a :: k). a :~: a
castDance :: (Typeable a, Typeable b) => a -> Maybe b
castDance = castR typeRep typeRep
withTypeable :: TypeRep a -> (Typeable a => r) -> r
castR :: TypeRep a -> TypeRep b -> a -> Maybe b
castR ta tb = withTypeable ta (withTypeable tb castDance)
cmpT = undefined
compareTypeRep = undefined
data TypeRepX where
TypeRepX :: TypeRep a -> TypeRepX
type TyMapLessTyped = Map TypeRepX Dynamic
insertLessTyped :: forall a. Typeable a => a -> TyMapLessTyped -> TyMapLessTyped
insertLessTyped x = Map.insert (TypeRepX (typeRep :: TypeRep a)) (toDynamic x)
lookupLessTyped :: forall a. Typeable a => TyMapLessTyped -> Maybe a
lookupLessTyped = fromDynamic <=< Map.lookup (TypeRepX (typeRep :: TypeRep a))
instance Ord TypeRepX where
compare (TypeRepX tr1) (TypeRepX tr2) = compareTypeRep tr1 tr2
compareTypeRep :: TypeRep a -> TypeRep b -> Ordering -- primitive
data TyMap = Empty | Node Dynamic TyMap TyMap
lookup :: TypeRep a -> TyMap -> Maybe a
lookup tr1 (Node (Dyn tr2 v) left right) =
case compareTypeRep tr1 tr2 of
LT -> lookup tr1 left
EQ -> castR tr2 tr1 v -- know this cast will succeed
GT -> lookup tr1 right
lookup tr1 Empty = Nothing
cmpT :: TypeRep a -> TypeRep b -> OrderingT a b
-- definition is primitive
data OrderingT a b where
LTT :: OrderingT a b
EQT :: OrderingT t t
GTT :: OrderingT a b
data TypeRep (a :: k) where
TrApp :: TypeRep a -> TypeRep b -> TypeRep (a b)
TrTyCon :: TyCon -> TypeRep k -> TypeRep (a :: k)
data TyCon = TyCon { tc_module :: Module, tc_name :: String }
data Module = Module { mod_pkg :: String, mod_name :: String }
tcMaybe :: TyCon
tcMaybe = TyCon { tc_module = Module { mod_pkg = "base"
, mod_name = "Data.Maybe" }
, tc_name = "Maybe" }
rt = undefined
delta1 :: Dynamic -> Dynamic
delta1 dn = case fromDynamic dn of
Just f -> f dn
Nothing -> dn
loop1 = delta1 (toDynamic delta1)
data Rid = MkT (forall a. TypeRep a -> a -> a)
rt :: TypeRep Rid
delta :: forall a. TypeRep a -> a -> a
delta ra x = case (eqT ra rt) of
Just Refl -> case x of MkT y -> y rt x
Nothing -> x
loop = delta rt (MkT delta)
throw# :: SomeException -> a
data SomeException where
SomeException :: Exception e => e -> SomeException
class (Typeable e, Show e) => Exception e where { }
data Company
data Salary
incS :: Float -> Salary -> Salary
incS = undefined
-- some impedance matching with SYB
instance Data.Data.Data Company
instance {-# INCOHERENT #-} Data.Typeable.Typeable a => Typeable a
mkT :: (Typeable a, Typeable b) => (b -> b) -> a -> a
mkT f x = case (cast f) of
Just g -> g x
Nothing -> x
data Expr a
frontEnd = undefined
data DynExp where
DE :: TypeRep a -> Expr a -> DynExp
frontEnd :: String -> DynExp
data TyConOld
typeOf = undefined
eqTOld = undefined
funTcOld = undefined :: TyConOld
splitTyConApp = undefined
mkTyCon3 = undefined
boolTcOld = undefined
tupleTc = undefined
mkTyConApp = undefined
instance Eq TypeRepOld
instance Eq TyConOld
data TypeRepOld -- Abstract
class TypeableOld a where
typeRepOld :: proxy a -> TypeRepOld
data DynamicOld where
DynOld :: TypeRepOld -> a -> DynamicOld
data Proxy a = Proxy
fromDynamicOld :: forall d. TypeableOld d => DynamicOld -> Maybe d
fromDynamicOld (DynOld trx x)
| typeRepOld (Proxy :: Proxy d) == trx = Just (unsafeCoerce x)
| otherwise = Nothing
dynApplyOld :: DynamicOld -> DynamicOld -> Maybe DynamicOld
dynApplyOld (DynOld trf f) (DynOld trx x) =
case splitTyConApp trf of
(tc, [t1,t2]) | tc == funTcOld && t1 == trx ->
Just (DynOld t2 ((unsafeCoerce f) x))
_ -> Nothing
data DynamicClosed where
DynClosed :: TypeRepClosed a -> a -> DynamicClosed
data TypeRepClosed (a :: *) where
TBool :: TypeRepClosed Bool
TFun :: TypeRepClosed a -> TypeRepClosed b -> TypeRepClosed (a -> b)
TProd :: TypeRepClosed a -> TypeRepClosed b -> TypeRepClosed (a, b)
lookupPil = undefined
lookupPil :: Typeable a => [Dynamic] -> Maybe a
data Dyn1 = Dyn1 Int
| DynFun (Dyn1 -> Dyn1)
| DynPair (Dyn1, Dyn1)
data TypeEnum = IntType | FloatType | BoolType | DateType | StringType
data Schema = Object [Schema] |
Field TypeEnum |
Array Schema
schema :: Typeable a => a -> Schema