hakaru-0.6.0: haskell/Tests/Pretty.hs
{-# LANGUAGE OverloadedStrings
, DataKinds
, GADTs
, TypeOperators
, FlexibleContexts #-}
module Tests.Pretty where
import Language.Hakaru.Command (parseAndInfer)
import Language.Hakaru.Pretty.Concrete
import Language.Hakaru.Syntax.ABT
import Language.Hakaru.Syntax.Prelude
import Language.Hakaru.Syntax.TypeCheck
import Language.Hakaru.Types.Sing
import Language.Hakaru.Types.DataKind
import qualified Language.Hakaru.Parser.AST as U
import qualified Language.Hakaru.Syntax.AST as T
import Language.Hakaru.Syntax.IClasses
import Language.Hakaru.Types.Sing
import Tests.TestTools
import Data.Text
import Text.PrettyPrint
import Test.HUnit
import Text.Parsec.Error
import Control.Monad.Trans.State.Strict (evalState)
import Prelude ((.), ($), asTypeOf, String, FilePath, Show(..), (++), Bool(..), concat
,Either(..), Maybe(..))
import qualified Prelude
allTests :: Test
allTests = test
[ "basic let" ~: testPretty letTest
, "nested let" ~: testPretty letTest2
, "basic fn" ~: testPretty defTest
, "nested fn" ~: testPretty defTest2
, "fn in case" ~: testPretty' caseFn
, "fn literal in case" ~: testPretty' caseFn2
, "hof" ~: testPretty' hof
]
letTest = unlines ["x = 2"
,"y = 3"
,"x"
]
letTest2 = unlines ["x = y = 2"
," y"
,"x"
]
defTest = unlines ["foo = fn x nat:"
," x + 2"
,"foo(3)"
]
defTest2 = unlines ["foo = fn x nat: fn y nat:"
," x + y"
,"foo(2,3)"
]
caseFn :: (ABT T.Term abt) => abt '[] 'HProb
caseFn =
pair (lam $ \x -> x) (lam $ \x -> x)
`unpair` \a b -> (a `app` prob_ 1) + (b `app` prob_ 2)
caseFn2 :: (ABT T.Term abt, b ~ HProb) => abt '[] (b :-> (b :-> (b :-> b)))
caseFn2 =
lam $ \x0 ->
let_ (lam $ \x1 ->
(lam $ \x2 ->
(pair (lam $ \x -> x) (prob_ 12)) `unpair` \x4 x5 -> x4 `app` (x0 + x1 + x2 + x5))) $ \x -> x
hof :: (ABT T.Term abt, a ~ HProb) => abt '[] (a :-> a :-> a :-> (a :-> (a :-> HPair a ((a :-> a) :-> a))) :-> a)
hof =
lam $ \x0 -> lam $ \x1 -> lam $ \x3 -> lam $ \x4 -> (
x4 `app` x0
`app` x1 `unpair` \x2 x3 ->
x3 `app` (lam $ \_ -> prob_ 1))
-- Tests things are parsed and prettyprinted nearly the same
testPretty :: Text -> Assertion
testPretty t =
case parseAndInfer t of
Left err -> assertFailure ("Program failed to parse\n" ++ unpack err)
Right (TypedAST ty ast) ->
case parseAndInfer $ pack $ show $ pretty ast of
Left err -> assertFailure ("Pretty printed program failed to parse\n" ++ unpack err)
Right (TypedAST ty' ast') ->
Prelude.maybe
(assertFailure $ mismatchMessage (prettyType 10) "Pretty printed programs has different type!" ty ty')
(\Refl -> assertAlphaEq "" ast ast')
(jmEq1 ty ty')
testPretty' :: TrivialABT T.Term '[] a -> Assertion
testPretty' = testPretty . pack . show . pretty