packages feed

hypertypes-0.2.2: test/LangATest.hs

{-# LANGUAGE OverloadedStrings #-}

module LangATest (test) where

import qualified Control.Lens as Lens
import Control.Lens.Operators
import Control.Monad.RWS
import Control.Monad.ST (runST)
import ExprUtils
import Hyper
import Hyper.Syntax.NamelessScope (EmptyScope)
import Hyper.Syntax.Scheme
import LangA
import Test.Tasty
import TypeLang

import Prelude

test :: TestTree
test =
    testGroup
        "infer LangA"
        [ testA lamXYx5 "Right (∀t0(*). ∀t1(*). (Int -> t0) -> t1 -> t0)"
        , testA infinite "Left (t0 occurs in itself, expands to: t0 -> t1)"
        , testA skolem "Left (SkolemEscape: t0)"
        , testA validForAll "Right (∀t0(*). t0 -> t0)"
        , testA nomLam "Right (Map[key: Int, value: Int] -> Map[key: Int, value: Int])"
        ]

testA :: HPlain (LangA EmptyScope) -> String -> TestTree
testA p expect =
    testCommon expr expect pureRes stRes
    where
        expr = p ^. hPlain
        pureRes = execPureInferA (inferExpr expr)
        stRes = runST (execSTInferA (inferExpr expr))

lamXYx5 :: HPlain (LangA EmptyScope)
lamXYx5 =
    -- λx y. x 5
    ALamP (ALamP (AVarP (Just Nothing) `AAppP` ALitP 5))

infinite :: HPlain (LangA EmptyScope)
infinite =
    -- λx. x x
    ALamP (AVarP Nothing `AAppP` AVarP Nothing)

skolem :: HPlain (LangA EmptyScope)
skolem =
    -- λx. (x : ∀a. a)
    ALamP
        ( ATypeSigP
            (AVarP Nothing)
            (Types (QVars (mempty & Lens.at "a" ?~ mempty)) (QVars mempty))
            (TVarP "a")
        )

validForAll :: HPlain (LangA EmptyScope)
validForAll =
    -- (λx. x) : ∀a. a -> a
    ATypeSigP
        (ALamP (AVarP Nothing))
        (Types (QVars (mempty & Lens.at "a" ?~ mempty)) (QVars mempty))
        (TVarP "a" `TFunP` TVarP "a")

nomLam :: HPlain (LangA EmptyScope)
nomLam =
    -- λx. (x : Map[key: Int, value: Int])
    ALamP
        ( ATypeSigP
            (AVarP Nothing)
            (Types (QVars mempty) (QVars mempty))
            ( TNomP
                "Map"
                ( Types
                    ( QVarInstances
                        ( mempty
                            & Lens.at "key" ?~ Pure TInt
                            & Lens.at "value" ?~ Pure TInt
                        )
                    )
                    (QVarInstances mempty)
                )
            )
        )