g2-0.2.0.0: tests/Typing.hs
{-# LANGUAGE OverloadedStrings #-}
module Typing (typingTests) where
import Prelude hiding (either, maybe)
import G2.Language
import Data.Maybe (isNothing)
import Test.Tasty
import Test.Tasty.HUnit
typingTests :: TestTree
typingTests =
testGroup "Typing"
[
testCase "Function application" $ assertBool "Function application failed" test1
, testCase "Polymorphic DataCon application" $ assertBool "Polymorphic DataCon application failed" test2
, testCase "Polymorphic Function application" $ assertBool "Polymorphic Function application failed" test3
, testCase "Polymorphic Function application 2" $ assertBool "Polymorphic Function application 2 failed" test4
, testCase "Polymorphic Function application 3" $ assertBool "Polymorphic Function application 3 failed" funcAppTest
, testCase "Polymorphic Function" $ assertBool "Polymorphic Function failed" funcTest
, testCase "Kind application" $ assertBool "Kind application failed" tyAppKindTest
, testCase "Specializes test 1" $ assertBool ".:: failed" specTest1
, testCase "Specializes test 2" $ assertBool ".:: failed" specTest2
, testCase "Specializes test 3" $ assertBool ".:: failed" specTest3
, testCase "Specializes false test 1" $ assertBool ".:: failed" specFalseTest1
, testCase "Specializes false test 2" $ assertBool ".:: failed" specFalseTest2
, testCase "Specializes false test 3" $ assertBool ".:: failed" specFalseTest3
]
test1 :: Bool
test1 = typeOf (App f1 x1) == int
test2 :: Bool
test2 = typeOf (App (App just (Type int)) x1) == TyApp maybe int
test3 :: Bool
test3 = typeOf
(App
(App
f2
(Type int)
)
x1
)
==
int
test4 :: Bool
test4 = typeOf
(App
(App
(App
f3
(Type int)
)
(Type float)
)
x1
)
==
float
funcAppTest :: Bool
funcAppTest = typeOf (App (App idDef (Type int)) x1) == int
funcTest :: Bool
funcTest = idDef .:: (TyForAll aid (TyFun a a))
tyAppKindTest :: Bool
tyAppKindTest = typeOf (TyApp either a) == TyFun TYPE TYPE
specTest1 :: Bool
specTest1 = x1 .:: int
specTest2 :: Bool
specTest2 = x1 .:: a
specTest3 :: Bool
specTest3 = f2 .:: typeOf f3
specFalseTest1 :: Bool
specFalseTest1 = not $ Var (Id (Name "x1" Nothing 0 Nothing) a) .:: int
specFalseTest2 :: Bool
specFalseTest2 = not $ f3 .:: typeOf f2
specFalseTest3 :: Bool
specFalseTest3 =
let
c = Id (Name "c" Nothing 0 Nothing) TYPE
t1 = TyFun (TyVar aid) (TyVar bid)
t2 = TyFun (TyVar c) (TyVar c)
in
isNothing $ t1 `specializes` t2
-- Typed Expr's
x1 :: Expr
x1 = Var $ Id (Name "x1" Nothing 0 Nothing) int
f1 :: Expr
f1 = Var $ Id (Name "f1" Nothing 0 Nothing) (TyFun int int)
f2 :: Expr
f2 = Var $ Id (Name "f2" Nothing 0 Nothing)
(TyForAll
bid
(TyFun b b)
)
f3 :: Expr
f3 = Var $ Id (Name "f3" Nothing 0 Nothing)
(TyForAll
bid
(TyForAll
aid
(TyFun b a)
)
)
just :: Expr
just = Data $ DataCon
(Name "Just" Nothing 0 Nothing)
(TyForAll
aid
(TyFun a (TyApp maybe a))
)
idDef :: Expr
idDef = Lam TypeL aid
(Lam TermL
(Id (Name "x" Nothing 0 Nothing) a)
(Var (Id (Name "x" Nothing 0 Nothing) a))
)
-- Types
int :: Type
int = TyCon (Name "Int" Nothing 0 Nothing) TYPE
float :: Type
float = TyCon (Name "Float" Nothing 0 Nothing) TYPE
maybe :: Type
maybe = TyCon (Name "Maybe" Nothing 0 Nothing) (TyFun TYPE TYPE)
either :: Type
either = TyCon (Name "Either" Nothing 0 Nothing) (TyFun TYPE (TyFun TYPE TYPE))
a :: Type
a = TyVar aid
aid :: Id
aid = Id (Name "a" Nothing 0 Nothing) TYPE
b :: Type
b = TyVar bid
bid :: Id
bid = Id (Name "b" Nothing 0 Nothing) TYPE