Initial working implementation

This commit is contained in:
Anupam Jain 2021-01-06 11:46:16 +05:30
parent 4f9fa2e3b4
commit 6b6258f632
4 changed files with 109 additions and 13 deletions

View File

@ -1,10 +0,0 @@
module Main where
import Prelude
import Effect (Effect)
import Effect.Console (log)
main :: Effect Unit
main = do
log "🍝"

42
src/Typeable.js Normal file
View File

@ -0,0 +1,42 @@
exports.typerepImpl1 = function(t1) {
return t1;
};
exports.typerepImpl2 = function(t1) {
return function(t2) {
return [t1,t2];
};
};
exports.typerepImpl3 = function(t1) {
return function(t2) {
return function(t3) {
return [t1,t2,t3];
};
};
};
exports.eqTypeRep = function(t1) {
return function(t2) {
return nestedArrayEq(t1, t2);
};
};
exports.clog = function(a) {
return function() {
console.log("CLOG:", a);
};
};
function nestedArrayEq(t1, t2) {
if(Array.isArray(t1)) {
if(!(Array.isArray(t2) && (t1.length == t2.length)))
return false;
for (var i=0; i<t1.length;i++) {
if(!nestedArrayEq(t1[i], t2[i]))
return false;
}
return true;
}
return t1 === t2;
}

37
src/Typeable.purs Normal file
View File

@ -0,0 +1,37 @@
module Typeable where
import Data.Unit (Unit)
import Effect (Effect)
-- Indexed Typereps
data TypeRep a
-- Typeable class
class Typeable a where
typeRep :: TypeRep a
-- Implementation detail
-- Tagging types
data Proxy1 a = Proxy1
data Proxy2 (t :: Type -> Type) = Proxy2
data Proxy3 (t :: Type -> Type -> Type) = Proxy3
class Tag1 a where t1 :: Proxy1 a
class Tag2 (a :: Type -> Type) where t2 :: Proxy2 a
class Tag3 (a :: Type -> Type -> Type) where t3 :: Proxy3 a
-- Constructors for the opaque data type
foreign import typerepImpl1 :: forall a. Tag1 a => TypeRep a
foreign import typerepImpl2 :: forall a b. Typeable b => Tag2 a => TypeRep (a b)
foreign import typerepImpl3 :: forall a b c. Typeable c => Typeable b => Tag1 c => TypeRep (a b c)
-- Type equality
foreign import eqTypeRep :: forall a b. TypeRep a -> TypeRep b -> Boolean
-- Common instances
instance tag1Int :: Tag1 Int where t1 = Proxy1
instance typeableInt :: Typeable Int where typeRep = typerepImpl1
instance tag2Array :: Tag2 Array where t2 = Proxy2
instance typeableArray :: Typeable a => Typeable (Array a) where typeRep = typerepImpl2
-- DEBUG: Console.log anything
foreign import clog :: forall a. a -> Effect Unit

View File

@ -3,9 +3,36 @@ module Test.Main where
import Prelude
import Effect (Effect)
import Effect.Class.Console (log)
import Typeable (class Tag1, class Tag2, class Typeable, Proxy1(..), Proxy2(..), TypeRep, clog, eqTypeRep, typeRep, typerepImpl1, typerepImpl2)
main :: Effect Unit
main = do
log "🍝"
log "You should add some tests."
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)))
where
typeArrPerson :: TypeRep (Array Person)
typeArrPerson = typeRep
newtype Person = Person { name :: String, location :: String }
newtype Person2 = Person2 { name :: String, location :: String }
-- Create Typeable instances for Person
instance tag1Person :: Tag1 Person where t1 = Proxy1
instance typeablePerson :: Typeable Person where typeRep = typerepImpl1
-- Create Typeable instances for Person2
instance tag1Person2 :: Tag1 Person2 where t1 = Proxy1
instance typeablePerson2 :: Typeable Person2 where typeRep = typerepImpl1
data Optional a = None | Some a
-- Create Typeable instances for Person
instance tag2Optional :: Tag2 Optional where t2 = Proxy2
instance typeableOptional :: Typeable a => Typeable (Optional a) where
typeRep = typerepImpl2
typeRepFromVal :: forall a. Typeable a => a -> TypeRep a
typeRepFromVal _ = typeRep