{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Data.Monoid
import Data.Override
import GHC.Generics (Generic)
import Test.Hspec
main :: IO ()
main = hspec do
describe "Override" do
describe "Semigroup" do
it "Rec1" testRec1'Semigroup
describe "Monoid" do
it "Rec1" testRec1'Monoid
describe "Eq" do
it "Rec2" testRec2'Eq
describe "Ord" do
it "Rec2" testRec2'Ord
-- | Overriding instances by type.
data Rec1 = Rec1
{ foo :: String
, bar :: Bool
} deriving stock (Show, Eq, Generic)
deriving (Semigroup, Monoid)
via Override Rec1
'[ Bool `As` Any
]
testRec1'Semigroup :: IO ()
testRec1'Semigroup = do
Rec1 { foo = "a", bar = False }
<> Rec1 { foo = "b", bar = True }
`shouldBe` Rec1 { foo = "ab", bar = True }
testRec1'Monoid :: IO ()
testRec1'Monoid = do
mempty `shouldBe` Rec1 { foo = "", bar = False }
Rec1 { foo = "a", bar = False }
`mappend` Rec1 { foo = "b", bar = True }
`shouldBe` Rec1 { foo = "ab", bar = True }
data Rec2 = Rec2 String Int
deriving stock (Show, Generic)
deriving (Eq, Ord) via (Override Rec2 '[String `As` ByLength])
newtype ByLength = ByLength { byLength :: String }
deriving (Show)
instance Eq ByLength where
ByLength x == ByLength y = length x == length y
instance Ord ByLength where
ByLength x <= ByLength y = length x <= length y
testRec2'Eq :: IO ()
testRec2'Eq = do
(Rec2 "foo" 0 == Rec2 "bar" 0) `shouldBe` True
(Rec2 "foo" 0 == Rec2 "bar" 1) `shouldBe` False
(Rec2 "" 0 == Rec2 "bar" 0) `shouldBe` False
testRec2'Ord :: IO ()
testRec2'Ord = do
(Rec2 "foo" 0 <= Rec2 "bar" 0) `shouldBe` True
(Rec2 "foo" 1 <= Rec2 "bar" 0) `shouldBe` False
(Rec2 "" 0 >= Rec2 "bar" 0) `shouldBe` False