mirror of
https://github.com/yaitskov/purescript-typeable.git
synced 2024-12-28 13:53:05 +00:00
Initial working implementation
This commit is contained in:
parent
4f9fa2e3b4
commit
6b6258f632
@ -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
42
src/Typeable.js
Normal 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
37
src/Typeable.purs
Normal 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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user