2021-01-06 05:04:30 +00:00
|
|
|
module Test.Main where
|
|
|
|
|
|
|
|
import Prelude
|
|
|
|
|
2021-04-22 12:08:28 +00:00
|
|
|
import Control.Monad.Error.Class (class MonadThrow)
|
2021-01-06 16:12:20 +00:00
|
|
|
import Data.Either (Either)
|
2021-04-22 10:40:00 +00:00
|
|
|
import Data.Typeable (class TagT, TypeRep, eqTypeRep, proxyT, typeRep, typeRepFromVal)
|
2021-01-06 05:04:30 +00:00
|
|
|
import Effect (Effect)
|
2021-04-22 12:08:28 +00:00
|
|
|
import Effect.Aff (launchAff_)
|
|
|
|
import Effect.Exception (Error)
|
|
|
|
import Test.Spec (describe, it)
|
|
|
|
import Test.Spec.Assertions (shouldEqual)
|
|
|
|
import Test.Spec.Reporter.Console (consoleReporter)
|
|
|
|
import Test.Spec.Runner (runSpec)
|
2021-01-10 21:46:31 +00:00
|
|
|
|
|
|
|
foreign import clog :: forall a. a -> Effect Unit
|
2021-01-06 05:04:30 +00:00
|
|
|
|
2021-04-22 12:08:28 +00:00
|
|
|
assert :: forall m. MonadThrow Error m => Boolean -> m Unit
|
|
|
|
assert = shouldEqual true
|
2023-07-04 12:47:36 +00:00
|
|
|
|
2021-04-22 12:08:28 +00:00
|
|
|
deny :: forall m. MonadThrow Error m => Boolean -> m Unit
|
|
|
|
deny = shouldEqual false
|
|
|
|
|
2021-01-06 05:04:30 +00:00
|
|
|
main :: Effect Unit
|
|
|
|
main = do
|
2023-07-04 12:47:36 +00:00
|
|
|
launchAff_ $ runSpec [ consoleReporter ] do
|
2021-04-22 12:08:28 +00:00
|
|
|
describe "Typeable" do
|
|
|
|
it "can handle primitives" do
|
|
|
|
deny $ eqTypeRep (typeRep :: _ Int) (typeRep :: _ Char)
|
|
|
|
it "can handle unsaturated types" do
|
|
|
|
assert $ eqTypeRep (typeRep :: _ Array) (typeRep :: _ Array)
|
|
|
|
it "can handle mixed arity" do
|
|
|
|
deny $ eqTypeRep (typeRep :: _ Array) (typeRep :: _ Person)
|
|
|
|
it "can handle user defined data types" do
|
|
|
|
assert $ eqTypeRep (typeRep :: _ Person) typePerson
|
|
|
|
assert $ eqTypeRep (typeRep :: _ Optional) (typeRep :: _ Optional)
|
|
|
|
deny $ eqTypeRep (typeRep :: _ (Optional Int)) (typeRep :: _ (Optional Char))
|
|
|
|
it "can distinguish between distinct types with matching fields" do
|
|
|
|
deny $ eqTypeRep (typeRep :: _ Person) (typeRep :: _ Person2)
|
|
|
|
it "can handle nested types" do
|
|
|
|
assert $ eqTypeRep (typeRep :: _ (Either Int Person)) (typeRep :: _ (Either Int Person))
|
|
|
|
assert $ eqTypeRep (typeRep :: _ (Array Person)) typeArrPerson
|
|
|
|
deny $ eqTypeRep (typeRep :: _ (Array Person2)) typeArrPerson
|
2023-07-04 12:47:36 +00:00
|
|
|
-- it "can handle bare records" do
|
|
|
|
-- assert $ eqTypeRep typeRecord (typeRep :: _ { name :: String, age :: Int })
|
2021-04-22 12:08:28 +00:00
|
|
|
it "can generate type reps from values" do
|
|
|
|
assert $ eqTypeRep (typeRep :: _ (Optional Int)) (typeRepFromVal (Some 1))
|
|
|
|
deny $ eqTypeRep (typeRep :: _ (Optional Person)) (typeRepFromVal (Some 1))
|
|
|
|
|
2023-07-04 12:47:36 +00:00
|
|
|
clog (eqTypeRep (typeRep :: _ Int) (typeRep :: _ Char))
|
|
|
|
clog (eqTypeRep (typeRep :: _ Int) (typeRep :: _ Int))
|
|
|
|
clog (typeRep :: _ Char)
|
|
|
|
clog (typeRep :: _ Int)
|
2021-04-22 12:08:28 +00:00
|
|
|
|
2023-07-04 12:47:36 +00:00
|
|
|
clog (typeRep :: _ Array)
|
|
|
|
-- clog (typeRep :: _ { name :: String, age :: Int })
|
|
|
|
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 :: _ (Foo Int Int Int))
|
2021-04-22 10:40:00 +00:00
|
|
|
|
2021-01-06 06:16:16 +00:00
|
|
|
where
|
2023-07-04 12:47:36 +00:00
|
|
|
-- typeRecord :: TypeRep { age :: Int, name :: String }
|
|
|
|
-- typeRecord = typeRep
|
|
|
|
|
|
|
|
typeArrPerson :: TypeRep (Array Person)
|
|
|
|
typeArrPerson = typeRep
|
|
|
|
|
|
|
|
typePerson :: TypeRep Person
|
|
|
|
typePerson = typeRep
|
|
|
|
|
|
|
|
-- The following should not compile since Break does not have a typeable instance
|
|
|
|
-- typeRecordBreak :: TypeRep {break::Break, name::String}
|
|
|
|
-- typeRecordBreak = typeRep
|
2021-01-11 20:04:12 +00:00
|
|
|
|
|
|
|
-- A data type without a typeable instance
|
|
|
|
data Break
|
2021-01-06 06:16:16 +00:00
|
|
|
|
2021-04-22 10:40:00 +00:00
|
|
|
data Foo :: forall k1 k2 k3. k1 -> k2 -> k3 -> Type
|
2021-01-10 21:46:31 +00:00
|
|
|
data Foo a b c = Foo
|
2023-07-04 12:47:36 +00:00
|
|
|
|
|
|
|
instance tagFoo :: TagT Foo where
|
|
|
|
tagT = proxyT
|
2021-01-06 06:16:16 +00:00
|
|
|
|
|
|
|
newtype Person = Person { name :: String, location :: String }
|
2023-07-04 12:47:36 +00:00
|
|
|
|
|
|
|
instance tagTPerson :: TagT Person where
|
|
|
|
tagT = proxyT
|
2021-01-06 06:16:16 +00:00
|
|
|
|
2021-01-10 21:46:31 +00:00
|
|
|
newtype Person2 = Person2 { name :: String, location :: String }
|
2023-07-04 12:47:36 +00:00
|
|
|
|
|
|
|
instance tagTPerson2 :: TagT Person2 where
|
|
|
|
tagT = proxyT
|
2021-01-06 06:16:16 +00:00
|
|
|
|
|
|
|
data Optional a = None | Some a
|
2023-07-04 12:47:36 +00:00
|
|
|
|
|
|
|
instance tagOptional :: TagT Optional where
|
|
|
|
tagT = proxyT
|