hindley-milner-0.1.0.0: test/Language/HM/AlgorithmWSpec.hs
--------------------------------------------------------------------------------
module Language.HM.AlgorithmWSpec where
--------------------------------------------------------------------------------
import Test.Hspec
import Language.HM
import Language.HM.AlgorithmW
--------------------------------------------------------------------------------
e0 :: Term
e0 = varE "x"
e1 :: Term
e1 = letE "id" (absE "x" (varE "x")) (varE "id")
t1 :: Tau
t1 = varT "a" `arrowT` varT "a"
e2 :: Term
e2 = letE "id"
(absE "x" (varE "x"))
(appE (varE "id") (varE "id"))
e3 :: Term
e3 = letE "id"
(absE "x" (letE "y" (varE "x") (varE "y")))
(appE (varE "id") (varE "id"))
e4 :: Term
e4 = letE "id"
(absE "x" (appE (varE "x") (varE "x")))
(varE "id")
-- | 'alphaEqOf' @t r@ is a predicate which tests that the result of some
-- type inference process @r@ is successful and alpha-equivalent to @t@.
alphaEqOf :: Tau -> Either TypeError Tau -> Bool
alphaEqOf _ (Left _) = False
alphaEqOf t (Right t') = alphaEq (genInOrder empty t) (genInOrder empty t')
occursFailure :: Either TypeError Tau -> Bool
occursFailure (Left (OccursErr _ _)) = True
occursFailure _ = False
spec :: Spec
spec = do
it "not in scope" $ inferW empty e0 `shouldBe` Left (NotInScopeErr "x")
it "identity function 1" $ inferW empty e1 `shouldSatisfy` alphaEqOf t1
it "identity function 2" $ inferW empty e2 `shouldSatisfy` alphaEqOf t1
it "identity function 3" $ inferW empty e3 `shouldSatisfy` alphaEqOf t1
it "identity function 4" $ inferW empty e4 `shouldSatisfy` occursFailure
--------------------------------------------------------------------------------