Use polykinds in Purescript 0.14

This commit is contained in:
Anupam Jain 2021-04-22 16:10:00 +05:30
parent d6a4c80b81
commit 1eabe79427
7 changed files with 382 additions and 161 deletions

279
attic/Data.purs Normal file
View File

@ -0,0 +1,279 @@
module Data.Data where
import Control.Alt ((<|>))
import Control.Alternative (empty)
import Control.Applicative (pure)
import Control.Bind (bind, (>>=))
import Control.Category (identity, (<<<))
import Control.Monad (class Monad)
import Control.MonadPlus (class MonadPlus)
import Data.Array as A
import Data.CommutativeRing ((+))
import Data.Const (Const(..))
import Data.Either (Either(..))
import Data.Eq ((==))
import Data.Foldable (foldl)
import Data.Function (const, ($))
import Data.Identity (Identity(..))
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Newtype (unwrap)
import Data.Ordering (Ordering)
import Data.Tuple (Tuple(..))
import Data.Typeable (class Tag0, class Tag1, class Typeable, cast)
import Data.Unit (Unit)
import Unsafe.Coerce (unsafeCoerce)
mkT :: forall a b. Typeable a => Typeable b => (b -> b) -> a -> a
mkT f = fromMaybe identity (cast f)
mkQ :: forall a b r. Typeable a => Typeable b => r -> (b -> r) -> a -> r
mkQ r q a = maybe r q (cast a)
mkM :: forall a b m. Typeable a => Typeable b => Monad m => Tag1 m => (b -> m b) -> a -> m a
mkM f = fromMaybe pure (cast f)
-- Purescript can't have cycles in typeclasses
-- So we manually reify the dictionary into the DataDict datatype
-- Not using wrapped records here because Purescript can't handle constraints inside records
newtype DataDict a = DataDict
(forall c. (forall d b. Data d => c (d -> b) -> d -> c b)
-- ^ defines how nonempty constructor applications are
-- folded. It takes the folded tail of the constructor
-- application and its head, i.e., an immediate subterm,
-- and combines them in some way.
-> (forall g. g -> c g)
-- ^ defines how the empty constructor application is
-- folded, like the neutral \/ start element for list
-- folding.
-> a
-- ^ structure to be folded.
-> c a
-- ^ result, with a type defined in terms of @a@, but
-- variability is achieved by means of type constructor
-- @c@ for the construction of the actual result type.
)
gfoldl :: forall a c. Data a => (forall d b. Data d => c (d -> b) -> d -> c b)
-- ^ defines how nonempty constructor applications are
-- folded. It takes the folded tail of the constructor
-- application and its head, i.e., an immediate subterm,
-- and combines them in some way.
-> (forall g. g -> c g)
-- ^ defines how the empty constructor application is
-- folded, like the neutral \/ start element for list
-- folding.
-> a
-- ^ structure to be folded.
-> c a
-- ^ result, with a type defined in terms of @a@, but
-- variability is achieved by means of type constructor
-- @c@ for the construction of the actual result type.
gfoldl = let DataDict f = dataDict in f
class Typeable a <= Data a where
dataDict :: DataDict a
-- | A generic transformation that maps over the immediate subterms
--
-- The default definition instantiates the type constructor @c@ in the
-- type of 'gfoldl' to an identity datatype constructor, using the
-- isomorphism pair as injection and projection.
gmapT :: forall a. Data a => (forall b. Data b => b -> b) -> a -> a
-- Use the Identity datatype constructor
-- to instantiate the type constructor c in the type of gfoldl,
-- and perform injections Identity and projections runIdentity accordingly.
--
gmapT f x0 = unwrap (gfoldl k Identity x0)
where
k :: forall d b. Data d => Identity (d->b) -> d -> Identity b
k (Identity c) x = Identity (c (f x))
-- | A generic query with a left-associative binary operator
gmapQl :: forall a r r'. Data a => (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r
gmapQl o r f = unwrap <<< gfoldl k z
where
k :: forall d b. Data d => Const r (d->b) -> d -> Const r b
k c x = Const $ (unwrap c) `o` f x
z :: forall g. g -> Const r g
z _ = Const r
-- | A generic query with a right-associative binary operator
gmapQr :: forall a r r'. Data a => (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r
gmapQr o r0 f x0 = unQr (gfoldl k (const (Qr identity)) x0) r0
where
k :: forall d b. Data d => Qr r (d->b) -> d -> Qr r b
k (Qr c) x = Qr (\r -> c (f x `o` r))
-- | A generic query that processes the immediate subterms and returns a list
-- of results. The list is given in the same order as originally specified
-- in the declaration of the data constructors.
gmapQ :: forall a u. Data a => (forall d. Data d => d -> u) -> a -> Array u
gmapQ f = gmapQr (A.cons) [] f
-- | A generic query that processes one child by index (zero-based)
gmapQi :: forall u a. Data a => Int -> (forall d. Data d => d -> u) -> a -> u
gmapQi i f x = case gfoldl k z x of Qi _ q -> case q of
Nothing -> unsafeCoerce "UNEXPECTED NOTHING"
Just q' -> q'
where
k :: forall d b. Data d => Qi u (d -> b) -> d -> Qi u b
k (Qi i' q) a = Qi (i'+1) (if i==i' then Just (f a) else q)
z :: forall g q. g -> Qi q g
z _ = Qi 0 Nothing
-- | A generic monadic transformation that maps over the immediate subterms
--
-- The default definition instantiates the type constructor @c@ in
-- the type of 'gfoldl' to the monad datatype constructor, defining
-- injection and projection using 'return' and '>>='.
gmapM :: forall m a. Data a => Monad m => (forall d. Data d => d -> m d) -> a -> m a
-- Use immediately the monad datatype constructor
-- to instantiate the type constructor c in the type of gfoldl,
-- so injection and projection is done by return and >>=.
--
gmapM f = gfoldl k pure
where
k :: forall b d. Data d => m (d -> b) -> d -> m b
k c x = do c' <- c
x' <- f x
pure (c' x')
-- | Transformation of at least one immediate subterm does not fail
gmapMp :: forall m a. Data a => MonadPlus m => (forall d. Data d => d -> m d) -> a -> m a
{-
The type constructor that we use here simply keeps track of the fact
if we already succeeded for an immediate subterm; see Mp below. To
this end, we couple the monadic computation with a Boolean.
-}
gmapMp f x = unMp (gfoldl k z x) >>= \(Tuple x' b) ->
if b then pure x' else empty
where
z :: forall g. g -> Mp m g
z g = Mp (pure (Tuple g false))
k :: forall d b. Data d => Mp m (d -> b) -> d -> Mp m b
k (Mp c) y
= Mp ( c >>= \(Tuple h b) ->
(f y >>= \y' -> pure (Tuple (h y') true))
<|> pure (Tuple (h y) b)
)
-- | Transformation of one immediate subterm with success
gmapMo :: forall m a. Data a => MonadPlus m => (forall d. Data d => d -> m d) -> a -> m a
{-
We use the same pairing trick as for gmapMp,
i.e., we use an extra Boolean component to keep track of the
fact whether an immediate subterm was processed successfully.
However, we cut of mapping over subterms once a first subterm
was transformed successfully.
-}
gmapMo f x = unMp (gfoldl k z x) >>= \(Tuple x' b) ->
if b then pure x' else empty
where
z :: forall g. g -> Mp m g
z g = Mp (pure (Tuple g false))
k :: forall d b. Data d => Mp m (d -> b) -> d -> Mp m b
k (Mp c) y
= Mp ( c >>= \(Tuple h b) -> if b
then pure (Tuple (h y) b)
else (f y >>= \y' -> pure (Tuple (h y') true))
<|> pure (Tuple (h y) b)
)
-- | Type constructor for adding counters to queries
data Qi q a = Qi Int (Maybe q)
-- | The type constructor used in definition of gmapQr
newtype Qr r a = Qr (r -> r)
unQr :: forall r a. Qr r a -> r -> r
unQr (Qr f) = f
-- | The type constructor used in definition of gmapMp
newtype Mp m x = Mp (m (Tuple x Boolean))
unMp :: forall m x. Mp m x -> m (Tuple x Boolean)
unMp (Mp f) = f
-- | Left-associative fold operation for constructor applications.
--
-- The type of 'gfoldl' is a headache, but operationally it is a simple
-- generalisation of a list fold.
--
-- The default definition for 'gfoldl' is @'const' 'id'@, which is
-- suitable for abstract datatypes with no substructures.
-- gfoldl
-- TODO: Why do we need `Tag0` here? Instead of `Typeable`.
instance dataArray :: (Tag0 a, Data a) => Data (Array a) where
dataDict = DataDict \k z arr -> case A.uncons arr of
Nothing -> z []
Just x -> (z A.cons `k` x.head) `k` x.tail
instance dataMaybe :: (Tag0 a, Data a) => Data (Maybe a) where
dataDict = DataDict \k z e -> case e of
Nothing -> z Nothing
Just a -> z Just `k` a
instance dataEither :: (Tag0 a, Tag0 b, Data a, Data b) => Data (Either a b) where
dataDict = DataDict \k z e -> case e of
Left a -> z Left `k` a
Right b -> z Right `k` b
instance dataBoolean :: Data Boolean where
dataDict = DataDict \k z x -> z x
instance dataInt :: Data Int where
dataDict = DataDict \k z x -> z x
instance dataNumber :: Data Number where
dataDict = DataDict \k z x -> z x
instance dataChar :: Data Char where
dataDict = DataDict \k z x -> z x
instance dataString :: Data String where
dataDict = DataDict \k z x -> z x
instance dataUnit :: Data Unit where
dataDict = DataDict \k z x -> z x
instance dataOrdering :: Data Ordering where
dataDict = DataDict \k z x -> z x
-- Combinators
-- | Apply a transformation everywhere, bottom-up
everywhere :: forall a. Data a => (forall b. Data b => b -> b) -> a -> a
everywhere f x = f (gmapT (everywhere f) x)
-- | Apply a transformation everywhere, top-down
everywhere' :: forall a. Data a => (forall b. Data b => b -> b) -> a -> a
everywhere' f x = gmapT (everywhere' f) (f x)
-- | Summarise all nodes in top-down, left-to-right
everything :: forall a r. Data a => (r -> r -> r) -> (forall b. Data b => b -> r) -> a -> r
everything k f x = foldl k (f x) (gmapQ (everything k f) x)
-- | Apply a monadic transformation everywhere, bottom-up
everywhereM :: forall m a. Monad m => Data a => (forall b. Data b => b -> m b) -> a -> m a
everywhereM f x = gmapM (everywhereM f) x >>= f

21
attic/Dynamic.purs Normal file
View File

@ -0,0 +1,21 @@
module Data.Dynamic where
import Data.Exists (Exists, mkExists, runExists)
import Data.Function ((#))
import Data.Functor (map)
import Data.Leibniz (runLeibniz)
import Data.Maybe (Maybe)
import Data.Typeable (class Typeable, TypeRep, eqT, typeRep)
-- | A `Dynamic` holds a value `a` in a context `t`
-- | and forgets the type of `a`
data Dynamic' t a = Dynamic' (TypeRep a) (t a)
data Dynamic t = Dynamic (Exists (Dynamic' t))
-- | Wrap a value into a dynamic
dynamic :: forall t a. Typeable a => t a -> Dynamic t
dynamic a = Dynamic (mkExists (Dynamic' typeRep a))
-- | Extract a value from a dynamic
unwrapDynamic :: forall t a. TypeRep a -> Dynamic t -> Maybe (t a)
unwrapDynamic ta (Dynamic e) = e # runExists \(Dynamic' ti v) -> map (\w -> runLeibniz w v) (eqT ti ta)

View File

@ -19,7 +19,7 @@ import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Newtype (unwrap)
import Data.Ordering (Ordering)
import Data.Tuple (Tuple(..))
import Data.Typeable (class Tag0, class Tag1, class Typeable, cast)
import Data.Typeable (class TagT, class Typeable, cast)
import Data.Unit (Unit)
import Unsafe.Coerce (unsafeCoerce)
@ -29,7 +29,7 @@ mkT f = fromMaybe identity (cast f)
mkQ :: forall a b r. Typeable a => Typeable b => r -> (b -> r) -> a -> r
mkQ r q a = maybe r q (cast a)
mkM :: forall a b m. Typeable a => Typeable b => Monad m => Tag1 m => (b -> m b) -> a -> m a
mkM :: forall a b m. Typeable a => Typeable b => Monad m => TagT m => (b -> m b) -> a -> m a
mkM f = fromMaybe pure (cast f)
-- Purescript can't have cycles in typeclasses
@ -197,10 +197,12 @@ gmapMo f x = unMp (gfoldl k z x) >>= \(Tuple x' b) ->
-- | Type constructor for adding counters to queries
data Qi :: forall k. Type -> k -> Type
data Qi q a = Qi Int (Maybe q)
-- | The type constructor used in definition of gmapQr
newtype Qr :: forall k. Type -> k -> Type
newtype Qr r a = Qr (r -> r)
unQr :: forall r a. Qr r a -> r -> r
@ -223,42 +225,42 @@ unMp (Mp f) = f
-- gfoldl
-- TODO: Why do we need `Tag0` here? Instead of `Typeable`.
instance dataArray :: (Tag0 a, Data a) => Data (Array a) where
-- TODO: Why do we need `TagT` here? Instead of `Typeable`.
instance dataArray :: (TagT a, Data a) => Data (Array a) where
dataDict = DataDict \k z arr -> case A.uncons arr of
Nothing -> z []
Just x -> (z A.cons `k` x.head) `k` x.tail
instance dataMaybe :: (Tag0 a, Data a) => Data (Maybe a) where
instance dataMaybe :: (TagT a, Data a) => Data (Maybe a) where
dataDict = DataDict \k z e -> case e of
Nothing -> z Nothing
Just a -> z Just `k` a
instance dataEither :: (Tag0 a, Tag0 b, Data a, Data b) => Data (Either a b) where
instance dataEither :: (TagT a, TagT b, Data a, Data b) => Data (Either a b) where
dataDict = DataDict \k z e -> case e of
Left a -> z Left `k` a
Right b -> z Right `k` b
instance dataBoolean :: Data Boolean where
dataDict = DataDict \k z x -> z x
dataDict = DataDict \_ z x -> z x
instance dataInt :: Data Int where
dataDict = DataDict \k z x -> z x
dataDict = DataDict \_ z x -> z x
instance dataNumber :: Data Number where
dataDict = DataDict \k z x -> z x
dataDict = DataDict \_ z x -> z x
instance dataChar :: Data Char where
dataDict = DataDict \k z x -> z x
dataDict = DataDict \_ z x -> z x
instance dataString :: Data String where
dataDict = DataDict \k z x -> z x
dataDict = DataDict \_ z x -> z x
instance dataUnit :: Data Unit where
dataDict = DataDict \k z x -> z x
dataDict = DataDict \_ z x -> z x
instance dataOrdering :: Data Ordering where
dataDict = DataDict \k z x -> z x
dataDict = DataDict \_ z x -> z x
-- Combinators

View File

@ -9,6 +9,7 @@ import Data.Typeable (class Typeable, TypeRep, eqT, typeRep)
-- | A `Dynamic` holds a value `a` in a context `t`
-- | and forgets the type of `a`
data Dynamic' :: forall k. (k -> Type) -> k -> Type
data Dynamic' t a = Dynamic' (TypeRep a) (t a)
data Dynamic t = Dynamic (Exists (Dynamic' t))

View File

@ -5,39 +5,18 @@ exports.typeRepDefault0 = function(t) {
return t;
};
exports.typeRepFromTag1 = pack('tag1');
exports.typeRepFromTag1 = pack('tagT');
exports.showTypeRep = function(t) {
return "" + t;
};
exports.proxy0 = tag;
exports.proxy1 = tag;
exports.proxy2 = tag;
exports.proxy3 = tag;
exports.proxy4 = tag;
exports.proxy5 = tag;
exports.proxy6 = tag;
exports.proxy7 = tag;
exports.proxy8 = tag;
exports.proxy9 = tag;
exports.proxy10 = tag;
exports.proxy11 = tag;
exports.proxyT = tag;
// Just a JS class, instances of which can be tested for equality
function tag() {}
// exports.proxy0FromTag1 = pack('tag1');
exports.proxy1FromTag2 = pack('tag2');
exports.proxy2FromTag3 = pack('tag3');
exports.proxy3FromTag4 = pack('tag4');
exports.proxy4FromTag5 = pack('tag5');
exports.proxy5FromTag6 = pack('tag6');
exports.proxy6FromTag7 = pack('tag7');
exports.proxy7FromTag8 = pack('tag8');
exports.proxy8FromTag9 = pack('tag9');
exports.proxy9FromTag10 = pack('tag10');
exports.proxy10FromTag11 = pack('tag11');
exports.proxyTFromTagT = pack('tagT');
function pack(tagName) {
return function(origTag) {
@ -77,7 +56,7 @@ exports.typeRowCons = function(_) {
exports.typeRowNil = {record: []};
function eqTypeRepHelper(t1,t2) {
if(t1.tag0) return t1 === t2;
if(t1.tagT) return t1 === t2;
if(t1.tag !== t2.tag) return false;
if(t1.record) {
if(!t2.record) return false;

View File

@ -15,10 +15,8 @@ module Data.Typeable
, SomeTypeRep(..)
, wrapSomeTypeRep
, unwrapSomeTypeRep
, Proxy0, Proxy1, Proxy2, Proxy3, Proxy4, Proxy5, Proxy6, Proxy7, Proxy8, Proxy9, Proxy10, Proxy11
, proxy0, proxy1, proxy2, proxy3, proxy4, proxy5, proxy6, proxy7, proxy8, proxy9, proxy10, proxy11
, class Tag0, class Tag1, class Tag2, class Tag3, class Tag4, class Tag5, class Tag6, class Tag7, class Tag8, class Tag9, class Tag10, class Tag11
, tag0, tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11
, ProxyT, proxyT
, class TagT, tagT
) where
import Control.Category (identity)
@ -65,12 +63,12 @@ gcast a = m # map \f -> runLeibniz f a
where
m = eqT (typeRep :: _ a) (typeRep :: _ b)
gcast1 :: forall s t a c. Typeable a => Tag1 c => Tag1 s => Tag1 t => c (s a) -> Maybe (c (t a))
gcast1 :: forall s t a c. Typeable a => TagT c => TagT s => TagT t => c (s a) -> Maybe (c (t a))
gcast1 a = m # map \f -> runLeibniz f a
where
m = eqT (typeRep :: _ (s a)) (typeRep :: _ (t a))
gcast2 :: forall s t a b c. Typeable a => Typeable b => Tag1 c => Tag2 s => Tag2 t => c (s a b) -> Maybe (c (t a b))
gcast2 :: forall s t a b c. Typeable a => Typeable b => TagT c => TagT s => TagT t => c (s a b) -> Maybe (c (t a b))
gcast2 a = m # map \f -> runLeibniz f a
where
m = eqT (typeRep :: _ (s a b)) (typeRep :: _ (t a b))
@ -94,101 +92,33 @@ unwrapSomeTypeRep (SomeTypeRep e) f = e # runExists f
-- MACHINERY + INSTANCES
foreign import typeRepDefault0 :: forall a. Tag0 a => TypeRep a
foreign import typeRepFromTag1 :: forall a b. Tag1 a => Typeable b => TypeRep (a b)
foreign import typeRepDefault0 :: forall a. TagT a => TypeRep a
foreign import typeRepFromTag1 :: forall a b. TagT a => Typeable b => TypeRep (a b)
foreign import showTypeRep :: forall a. TypeRep a -> String
-- Tagging types
-- These would be a lot simpler after PolyKinds
data Proxy0 (t :: Type)
data Proxy1 (t :: Type -> Type)
data Proxy2 (t :: Type -> Type -> Type)
data Proxy3 (t :: Type -> Type -> Type -> Type)
data Proxy4 (t :: Type -> Type -> Type -> Type -> Type)
data Proxy5 (t :: Type -> Type -> Type -> Type -> Type -> Type)
data Proxy6 (t :: Type -> Type -> Type -> Type -> Type -> Type -> Type)
data Proxy7 (t :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type)
data Proxy8 (t :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type)
data Proxy9 (t :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type)
data Proxy10 (t :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type)
data Proxy11 (t :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type)
-- Tagging types, this is basically the same as `Type.Proxy`
-- but we don't want to export any constructors
data ProxyT :: forall k. k -> Type
data ProxyT t
foreign import proxy0 :: forall t. Proxy0 t
foreign import proxy1 :: forall t. Proxy1 t
foreign import proxy2 :: forall t. Proxy2 t
foreign import proxy3 :: forall t. Proxy3 t
foreign import proxy4 :: forall t. Proxy4 t
foreign import proxy5 :: forall t. Proxy5 t
foreign import proxy6 :: forall t. Proxy6 t
foreign import proxy7 :: forall t. Proxy7 t
foreign import proxy8 :: forall t. Proxy8 t
foreign import proxy9 :: forall t. Proxy9 t
foreign import proxy10 :: forall t. Proxy10 t
foreign import proxy11 :: forall t. Proxy11 t
foreign import proxyT :: forall t. ProxyT t
class Tag0 a where tag0 :: Proxy0 a
class Tag1 (a :: Type -> Type) where tag1 :: Proxy1 a
class Tag2 (a :: Type -> Type -> Type) where tag2 :: Proxy2 a
class Tag3 (a :: Type -> Type -> Type -> Type) where tag3 :: Proxy3 a
class Tag4 (a :: Type -> Type -> Type -> Type -> Type) where tag4 :: Proxy4 a
class Tag5 (a :: Type -> Type -> Type -> Type -> Type -> Type) where tag5 :: Proxy5 a
class Tag6 (a :: Type -> Type -> Type -> Type -> Type -> Type -> Type) where tag6 :: Proxy6 a
class Tag7 (a :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type) where tag7 :: Proxy7 a
class Tag8 (a :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type) where tag8 :: Proxy8 a
class Tag9 (a :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type) where tag9 :: Proxy9 a
class Tag10 (a :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type) where tag10 :: Proxy10 a
class Tag11 (a :: Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type -> Type) where tag11 :: Proxy11 a
class TagT :: forall k. k -> Constraint
class TagT a where tagT :: ProxyT a
-- foreign import proxy0FromTag1 :: forall t a. Tag1 t => Typeable a => Proxy0 (t a)
foreign import proxy1FromTag2 :: forall t a. Tag2 t => Typeable a => Proxy1 (t a)
foreign import proxy2FromTag3 :: forall t a. Tag3 t => Typeable a => Proxy2 (t a)
foreign import proxy3FromTag4 :: forall t a. Tag4 t => Typeable a => Proxy3 (t a)
foreign import proxy4FromTag5 :: forall t a. Tag5 t => Typeable a => Proxy4 (t a)
foreign import proxy5FromTag6 :: forall t a. Tag6 t => Typeable a => Proxy5 (t a)
foreign import proxy6FromTag7 :: forall t a. Tag7 t => Typeable a => Proxy6 (t a)
foreign import proxy7FromTag8 :: forall t a. Tag8 t => Typeable a => Proxy7 (t a)
foreign import proxy8FromTag9 :: forall t a. Tag9 t => Typeable a => Proxy8 (t a)
foreign import proxy9FromTag10 :: forall t a. Tag10 t => Typeable a => Proxy9 (t a)
foreign import proxy10FromTag11 :: forall t a. Tag11 t => Typeable a => Proxy10 (t a)
foreign import proxyTFromTagT :: forall t a. TagT t => Typeable a => ProxyT (t a)
instance typeableRecord :: (RL.RowToList rs ls, TypeableRecordFields ls) => Typeable (Record rs) where
typeRep = typeRowToTypeRep (typeableRecordFields (RLProxy :: _ ls))
else
instance tag0FromTag1 :: (Tag1 t, Typeable a) => Typeable (t a) where
instance tagTFromTag1 :: (TagT t, Typeable a) => Typeable (t a) where
typeRep = typeRepFromTag1
else
instance typeableTag0 :: Tag0 t => Typeable t where
instance typeableTagT :: TagT t => Typeable t where
typeRep = typeRepDefault0
instance tag1FromTag2 :: (Tag2 t, Typeable a) => Tag1 (t a) where
tag1 = proxy1FromTag2
instance tag2FromTag3 :: (Tag3 t, Typeable a) => Tag2 (t a) where
tag2 = proxy2FromTag3
instance tag3FromTag4 :: (Tag4 t, Typeable a) => Tag3 (t a) where
tag3 = proxy3FromTag4
instance tag4FromTag5 :: (Tag5 t, Typeable a) => Tag4 (t a) where
tag4 = proxy4FromTag5
instance tag5FromTag6 :: (Tag6 t, Typeable a) => Tag5 (t a) where
tag5 = proxy5FromTag6
instance tag6FromTag7 :: (Tag7 t, Typeable a) => Tag6 (t a) where
tag6 = proxy6FromTag7
instance tag7FromTag8 :: (Tag8 t, Typeable a) => Tag7 (t a) where
tag7 = proxy7FromTag8
instance tag8FromTag9 :: (Tag9 t, Typeable a) => Tag8 (t a) where
tag8 = proxy8FromTag9
instance tag9FromTag10 :: (Tag10 t, Typeable a) => Tag9 (t a) where
tag9 = proxy9FromTag10
instance tag10FromTag11 :: (Tag11 t, Typeable a) => Tag10 (t a) where
tag10 = proxy10FromTag11
instance tagTFromTagT :: (TagT t, Typeable a) => TagT (t a) where
tagT = proxyTFromTagT
-- COMMON INSTANCES
@ -220,35 +150,35 @@ instance typeableRecordFieldsCons
key = SProxy :: _ key
tail = typeableRecordFields (RLProxy :: _ rowlistTail)
instance taggedInt :: Tag0 Int where
tag0 = proxy0
instance taggedInt :: TagT Int where
tagT = proxyT
instance tag0Boolean :: Tag0 Boolean where
tag0 = proxy0
instance tagTBoolean :: TagT Boolean where
tagT = proxyT
instance tag0Number :: Tag0 Number where
tag0 = proxy0
instance tagTNumber :: TagT Number where
tagT = proxyT
instance tag0Char :: Tag0 Char where
tag0 = proxy0
instance tagTChar :: TagT Char where
tagT = proxyT
instance tag0String :: Tag0 String where
tag0 = proxy0
instance tagTString :: TagT String where
tagT = proxyT
instance tag0Unit :: Tag0 Unit where
tag0 = proxy0
instance tagTUnit :: TagT Unit where
tagT = proxyT
instance taggedArray :: Tag1 Array where
tag1 = proxy1
instance taggedArray :: TagT Array where
tagT = proxyT
instance taggedMaybe :: Tag1 Maybe where
tag1 = proxy1
instance taggedMaybe :: TagT Maybe where
tagT = proxyT
instance tag2Func :: Tag2 (->) where
tag2 = proxy2
instance tag2Func :: TagT (->) where
tagT = proxyT
instance tag2Either :: Tag2 Either where
tag2 = proxy2
instance tag2Either :: TagT Either where
tagT = proxyT
instance tag0Ordering :: Tag0 Ordering where
tag0 = proxy0
instance tagTOrdering :: TagT Ordering where
tagT = proxyT

View File

@ -3,26 +3,34 @@ module Test.Main where
import Prelude
import Data.Either (Either)
import Data.Typeable (class Tag0, class Tag1, class Tag3, TypeRep, eqTypeRep, proxy0, proxy1, proxy3, typeRep, typeRepFromVal)
import Data.Typeable (class TagT, TypeRep, eqTypeRep, proxyT, typeRep, typeRepFromVal)
import Effect (Effect)
foreign import clog :: forall a. a -> Effect Unit
main :: Effect Unit
main = do
clog (eqTypeRep (typeRep :: _ Int) (typeRep :: _ Char))
clog (eqTypeRep (typeRep :: _ Int) (typeRep :: _ Int))
clog (typeRep :: _ Char)
clog (typeRep :: _ Int)
clog (typeRep :: _ Array)
clog (typeRep :: _ {name::String, age::Int})
clog (eqTypeRep typeRecord (typeRep :: _ {name::String, age::Int}))
clog (eqTypeRep (typeRep :: _ Person) typePerson)
clog (eqTypeRep (typeRep :: _ (Array Person)) typeArrPerson)
clog (eqTypeRep (typeRep :: _ (Array Person2)) typeArrPerson)
clog (eqTypeRep (typeRep :: _ (Optional Int)) (typeRepFromVal (Some 1)))
clog (eqTypeRep (typeRep :: _ (Optional Person)) (typeRepFromVal (Some 1)))
clog (eqTypeRep (typeRep :: _ (Either Int Person)) (typeRep :: _ (Either Int Person)))
clog (typeRep :: _ (Int -> Either (Either Int Int) (Optional (Array (Person)))))
clog (typeRep :: _ (Either (Either Int Int) (Optional (Array (Person)))))
clog (typeRep :: _ (Either Int Int))
clog (typeRep :: _ Int)
clog (typeRep :: _ (Foo Int Int Int))
clog (eqTypeRep (typeRep :: _ Array) (typeRep :: _ Array))
clog (eqTypeRep (typeRep :: _ Person) typePerson)
clog (eqTypeRep (typeRep :: _ (Array Person)) typeArrPerson)
clog (eqTypeRep (typeRep :: _ (Array Person2)) typeArrPerson)
clog (eqTypeRep typeRecord (typeRep :: _ {name::String, age::Int}))
clog (eqTypeRep (typeRep :: _ (Optional Int)) (typeRepFromVal (Some 1)))
clog (eqTypeRep (typeRep :: _ (Optional Person)) (typeRepFromVal (Some 1)))
clog (eqTypeRep (typeRep :: _ (Either Int Person)) (typeRep :: _ (Either Int Person)))
where
typeRecord :: TypeRep {age::Int, name::String}
typeRecord = typeRep
@ -37,14 +45,15 @@ main = do
-- A data type without a typeable instance
data Break
data Foo :: forall k1 k2 k3. k1 -> k2 -> k3 -> Type
data Foo a b c = Foo
instance tag3Foo :: Tag3 Foo where tag3 = proxy3
instance tagFoo :: TagT Foo where tagT = proxyT
newtype Person = Person { name :: String, location :: String }
instance tag0Person :: Tag0 Person where tag0 = proxy0
instance tagTPerson :: TagT Person where tagT = proxyT
newtype Person2 = Person2 { name :: String, location :: String }
instance tag0Person2 :: Tag0 Person2 where tag0 = proxy0
instance tagTPerson2 :: TagT Person2 where tagT = proxyT
data Optional a = None | Some a
instance tag1Optional :: Tag1 Optional where tag1 = proxy1
instance tagOptional :: TagT Optional where tagT = proxyT