11{-# LANGUAGE TemplateHaskellQuotes #-}
2+
23module PlutusTx.Eq.TH (Eq (.. ), deriveEq ) where
34
4- import PlutusTx.Eq.Class
5- import PlutusTx.Bool ((&&) , Bool (True ))
6- import Prelude hiding (Eq , (==) , (&&) , Bool (True ))
5+ import Data.Deriving.Internal (varTToName )
76import Data.Foldable
87import Data.Traversable
98import Language.Haskell.TH as TH
109import Language.Haskell.TH.Datatype as TH
11- import Data.Deriving.Internal (varTToName )
10+ import PlutusTx.Bool (Bool (True ), (&&) )
11+ import PlutusTx.Eq.Class
12+ import Prelude hiding (Bool (True ), Eq , (&&) , (==) )
1213
13- {- | derive a PlutusTx.Eq instance for a datatype/newtype, similar to Haskell's `deriving stock Eq`.
14+ {-| derive a PlutusTx.Eq instance for a datatype/newtype, similar to Haskell's `deriving stock Eq`.
1415
15- One shortcoming compared to Haskell's deriving is that you cannot `PlutusTx.deriveEq` for polymorphic phantom types.
16- -}
16+ One shortcoming compared to Haskell's deriving is that you cannot `PlutusTx.deriveEq` for polymorphic phantom types. -}
1717deriveEq :: TH. Name -> TH. Q [TH. Dec ]
1818deriveEq name = do
1919 TH. DatatypeInfo
@@ -32,29 +32,37 @@ deriveEq name = do
3232 instanceType :: TH. Type
3333 instanceType = TH. AppT (TH. ConT ''Eq) $ foldl' TH. AppT (TH. ConT tyConName) tyVars
3434
35- pure <$> instanceD (pure instanceCxt) (pure instanceType)
36- [funD '(==) (fmap deriveEqCons cons <> [pure eqDefaultClause])
37- , TH. pragInlD '(==) TH. Inlinable TH. FunLike TH. AllPhases
38- ]
39-
35+ pure
36+ <$> instanceD
37+ (pure instanceCxt)
38+ (pure instanceType)
39+ [ funD '(==) (fmap deriveEqCons cons <> [pure eqDefaultClause])
40+ , TH. pragInlD '(==) TH. Inlinable TH. FunLike TH. AllPhases
41+ ]
4042
4143-- Clause: Cons1 l1 l2 l3 .. ln == Cons1 r1 r2 r3 .. rn
4244deriveEqCons :: ConstructorInfo -> Q Clause
43- deriveEqCons (ConstructorInfo {constructorName = name, constructorFields = fields })
44- = do
45- argsL <- for [1 .. length fields] $ \ i -> TH. newName (" l" <> show i <> " l" )
46- argsR <- for [1 .. length fields] $ \ i -> TH. newName (" r" <> show i <> " r" )
47- pure (TH. Clause [ConP name [] (fmap VarP argsL), ConP name [] (fmap VarP argsR)]
48- (NormalB $
49- case fields of
50- [] -> TH. ConE 'True
51- _ -> foldr1 (\ e acc -> TH. InfixE (pure e) (TH. VarE '(&&) ) (pure acc))
52- $ zipWith (\ argL argR ->
53- TH. InfixE (pure $ TH. VarE argL) (TH. VarE '(==) ) (pure $ TH. VarE argR)
54- ) argsL argsR
55- )
56- []
57- )
45+ deriveEqCons (ConstructorInfo {constructorName = name, constructorFields = fields}) =
46+ do
47+ argsL <- for [1 .. length fields] $ \ i -> TH. newName (" l" <> show i <> " l" )
48+ argsR <- for [1 .. length fields] $ \ i -> TH. newName (" r" <> show i <> " r" )
49+ pure
50+ ( TH. Clause
51+ [ConP name [] (fmap VarP argsL), ConP name [] (fmap VarP argsR)]
52+ ( NormalB $
53+ case fields of
54+ [] -> TH. ConE 'True
55+ _ ->
56+ foldr1 (\ e acc -> TH. InfixE (pure e) (TH. VarE '(&&) ) (pure acc)) $
57+ zipWith
58+ ( \ argL argR ->
59+ TH. InfixE (pure $ TH. VarE argL) (TH. VarE '(==) ) (pure $ TH. VarE argR)
60+ )
61+ argsL
62+ argsR
63+ )
64+ []
65+ )
5866
5967-- Clause: _ == _ = False
6068eqDefaultClause :: Clause
0 commit comments