1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
module Test.Some
( someTests
)
where
import Data.Type.Equality (TestEquality(testEquality), (:~:)(Refl))
import Control.Lens (Lens', lens, view, set)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (assertEqual, testCase)
import Data.Parameterized.Classes (ShowF)
import Data.Parameterized.Some (Some(Some), someLens)
data Item b where
BoolItem :: Item Bool
IntItem :: Item Int
instance Show (Item b) where
show =
\case
BoolItem -> "BoolItem"
IntItem -> "IntItem"
instance TestEquality Item where
testEquality x y =
case (x, y) of
(BoolItem, BoolItem) -> Just Refl
(IntItem, IntItem) -> Just Refl
_ -> Nothing
data Pair a b =
Pair
{ _fir :: a
, _sec :: Item b
}
-- This instance isn't compatible with the intended use of TestEquality (which
-- is supposed to be just for singletons), but it seems fine for tests.
instance Eq a => TestEquality (Pair a) where
testEquality x y =
case testEquality (_sec x) (_sec y) of
Just Refl -> if _fir x == _fir y then Just Refl else Nothing
Nothing -> Nothing
instance (Show a) => Show (Pair a b) where
show (Pair a b) = "Pair(" ++ show a ++ ", " ++ show b ++ ")"
instance Show a => ShowF (Pair a)
fir :: Lens' (Pair a b) a
fir = lens _fir (\s v -> s { _fir = v })
someFir :: Lens' (Some (Pair a)) a
someFir = someLens fir
someTests :: IO TestTree
someTests =
testGroup "Some" <$>
return
[ testCase "someLens: view . set" $
assertEqual
"view l . set l x == const x"
(view someFir (set someFir 5 (Some (Pair 1 BoolItem))))
(5 :: Int)
, testCase "someLens: set . set" $
assertEqual
"set l y . set l x == set l y"
(set someFir 4 (set someFir 5 (Some (Pair 1 IntItem))))
(Some (Pair (4 :: Int) IntItem))
]
|