large-anon-0.3.0: test/Test/Sanity/Merging.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
{-# OPTIONS_GHC -fplugin=Data.Record.Anon.Plugin #-}
module Test.Sanity.Merging (tests) where
import Data.SOP.BasicFunctors
import Test.Tasty
import Test.Tasty.HUnit
import Data.Record.Anon
import Data.Record.Anon.Advanced (Record)
import qualified Data.Record.Anon.Advanced as Anon
tests :: TestTree
tests = testGroup "Test.Sanity.Merging" [
testCase "concrete" test_concrete
, testCase "eqConstraint" test_eqConstraint
]
{-------------------------------------------------------------------------------
Example values
-------------------------------------------------------------------------------}
ab, ab' ::
Record I (Merge [ "a" := Bool , "b" := Int ]
[ "c" := Double , "d" := Char ])
ab = Anon.merge a b
ab' = Anon.merge a' b
a, a' :: Record I [ "a" := Bool, "b" := Int ]
a =
Anon.insert #a (I True)
$ Anon.insert #b (I (1 :: Int))
$ Anon.empty
a' =
Anon.insert #a (I False)
$ Anon.insert #b (I (1 :: Int))
$ Anon.empty
b :: Record I [ "c" := Double, "d" := Char ]
b = Anon.insert #c (I 3.14)
$ Anon.insert #d (I 'a')
$ Anon.empty
{-------------------------------------------------------------------------------
Tests proper
-------------------------------------------------------------------------------}
test_concrete :: Assertion
test_concrete = do
assertEqual "get" (I True) $ Anon.get #a ab
assertEqual "set" ab' $ Anon.set #a (I False) ab
-- | Test that type equalities are handled correctly
test_eqConstraint :: Assertion
test_eqConstraint = do
assertEqual "a" (I True) $ f1 ab
assertEqual "b" (I 1) $ f2 ab
assertEqual "c" (I 3.14) $ f3 ab
where
-- Single simple equality
f1 :: row ~ Merge [ "a" := Bool , "b" := Int ]
[ "c" := Double , "d" := Char ]
=> Record I row -> I Bool
f1 = Anon.get #a
-- Multiple (transitive) equalities
f2 :: ( tf1 ~ tf2
, tf2 ~ Merge
, row ~ tf1 [ "a" := Bool , "b" := Int ]
[ "c" := Double , "d" := Char ]
)
=> Record I row -> I Int
f2 = Anon.get #b
-- Equality with partial application
f3 :: ( merge ~ Merge [ "a" := Bool , "b" := Int ]
, row ~ merge [ "c" := Double , "d" := Char ]
)
=> Record I row -> I Double
f3 = Anon.get #c