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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
|
{-# OPTIONS_GHC -dsuppress-all #-}
{-# LANGUAGE
BangPatterns,
CPP,
DeriveFunctor,
DeriveFoldable,
DeriveTraversable,
DeriveGeneric,
DerivingVia,
EmptyCase,
EmptyDataDeriving,
TemplateHaskell
#-}
{-# LANGUAGE TypeOperators, TypeFamilies #-}
import Control.Applicative (liftA2)
import GHC.Generics
import Data.Coerce (coerce)
import Data.Semigroup (Sum(..), All(..))
import Test.Inspection
import Generic.Data
import Generic.Data.Microsurgery
( ProductSurgery
, CopyRep
, Surgery'(..)
)
import Inspection.Boilerplate
-- Test cases
data T = T Int Bool
deriving Generic
deriving (Semigroup, Monoid)
via ProductSurgery (CopyRep (Sum Int, All)) T
deriving (Eq, Ord)
via Generically T
mappendT, mappendTG :: T -> T -> T
mappendT (T a1 b1) (T a2 b2) = T (a1 + a2) (b1 && b2)
mappendTG x y = x <> y
memptyT, memptyTG :: T
memptyT = T 0 True
memptyTG = mempty
eqT, eqTG :: T -> T -> Bool
eqT (T a1 b1) (T a2 b2) = a1 == a2 && b1 == b2
eqTG = (==)
compareT, compareTG :: T -> T -> Ordering
compareT (T a1 b1) (T a2 b2) = compare a1 a2 <> compare b1 b2
compareTG = compare
inspect $ 'mappendT ==- 'mappendTG
inspect $ 'memptyT ==- 'memptyTG
inspect $ 'eqT ==- 'eqTG
inspect $ 'compareT ==- 'compareTG
data Empty a
deriving (Generic, Generic1, Eq, Ord, Functor, Foldable, Traversable)
-- Arity 0 (nullary)
data Ary0 a = Ary0
deriving (Generic, Generic1, Eq, Ord, Functor, Foldable, Traversable)
-- Arity 1 (unary) (Lazy, Strict, Newtype)
data Ary1 a = Ary1 a
deriving (Generic, Generic1, Eq, Ord, Functor, Foldable, Traversable)
data Ary1' a = Ary1' !a
deriving (Generic, Generic1, Eq, Ord, Functor, Foldable, Traversable)
newtype Ary1NT a = Ary1NT a
deriving (Generic, Generic1, Eq, Ord, Functor, Foldable, Traversable)
-- Arity 2 (binary)
data Ary2 a = Ary2 a a
deriving (Generic, Generic1, Eq, Ord, Functor, Foldable, Traversable)
-- Arity 4 (quaternary)
data Ary4 a = Ary4 a a [Int] [a]
deriving (Generic, Generic1, Eq, Ord, Functor, Foldable, Traversable)
-- A big sum of stuff
data Big a
= Big0
| Big1 a
| Big2 a a
| Big4 a a a a
| Big8 Int a [a] [Int] [a] a a a
deriving (Generic1, Eq, Ord, Functor, Foldable, Traversable)
-- Handwritten to add INLINE pragmas. TODO: get GHC to do this
instance Generic (Big a) where
type Rep (Big a) =
U1
:+: K1 () a
:+: (K1 () a :*: K1 () a)
:+: (K1 () a :*: K1 () a :*: K1 () a :*: K1 () a)
:+: ( K1 () Int :*: K1 () a :*: K1 () [a] :*: K1 () [Int]
:*: K1 () ([a]) :*: K1 () a :*: K1 () a :*: K1 () a)
from Big0 = L1 U1
from (Big1 x) = R1 (L1 (K1 x))
from (Big2 x1 x2) = R1 (R1 (L1 (K1 x1 :*: K1 x2)))
from (Big4 x1 x2 x3 x4) = R1 (R1 (R1 (L1 (K1 x1 :*: K1 x2 :*: K1 x3 :*: K1 x4))))
from (Big8 x1 x2 x3 x4 x5 x6 x7 x8) = R1 (R1 (R1 (R1 (K1 x1 :*: K1 x2 :*: K1 x3 :*: K1 x4 :*: K1 x5 :*: K1 x6 :*: K1 x7 :*: K1 x8))))
{-# INLINE from #-}
to (L1 _) = Big0
to (R1 (L1 (K1 x))) = Big1 x
to (R1 (R1 (L1 (K1 x1 :*: K1 x2)))) = Big2 x1 x2
to (R1 (R1 (R1 (L1 (K1 x1 :*: K1 x2 :*: K1 x3 :*: K1 x4))))) = Big4 x1 x2 x3 x4
to (R1 (R1 (R1 (R1 (K1 x1 :*: K1 x2 :*: K1 x3 :*: K1 x4 :*: K1 x5 :*: K1 x6 :*: K1 x7 :*: K1 x8))))) = Big8 x1 x2 x3 x4 x5 x6 x7 x8
{-# INLINE to #-}
-- Empty
-- Stock deriving of fmap does not use an EmptyCase.
fmapEmptyRS :: (a -> b) -> Empty a -> Empty b
fmapEmptyRS _ = coerce
foldMapEmptyRS :: Monoid m => (a -> m) -> Empty a -> m
foldMapEmptyRS _ _ = mempty
--
mk_eq' ''Empty [| \ _ _ -> True |]
inspect $ 'eqEmptyR ==- 'eqEmptyS
inspect $ 'eqEmptyR ==- 'eqEmptyG
mk_compare' ''Empty [| \ _ _ -> EQ |]
inspect $ 'compareEmptyR ==- 'compareEmptyS
inspect $ 'compareEmptyR ==- 'compareEmptyG
mk_fmap ''Empty [| \ _ v -> case v of {} |]
inspect $ 'fmapEmptyRS ==- 'fmapEmptyS
inspect $ 'fmapEmptyR ==- 'fmapEmptyG
mk_foldMap ''Empty [| \ _ v -> case v of {} |]
inspect $ 'foldMapEmptyRS ==- 'foldMapEmptyS
inspect $ 'foldMapEmptyR ==- 'foldMapEmptyG
-- No EmptyCase!
mk_foldr ''Empty [| \_ b _ -> b |]
inspect $ 'foldrEmptyR ==- 'foldrEmptyS
inspect $ 'foldrEmptyR ==- 'foldrEmptyG
mk_traverse ''Empty [| \ _ v -> case v of {} |]
inspect $ 'traverseEmptyS ==- 'traverseEmptyS
inspect $ 'traverseEmptyR ==- 'traverseEmptyG
mk_sequenceA ''Empty [| \ v -> case v of {} |]
inspect $ 'sequenceAEmptyS ==- 'sequenceAEmptyS
inspect $ 'sequenceAEmptyR ==- 'sequenceAEmptyG
-- Ary0
eqAry0RS :: Ary0 a -> Ary0 a -> Bool
eqAry0RS Ary0 Ary0 = True
compareAry0RS :: Ary0 a -> Ary0 a -> Ordering
compareAry0RS Ary0 Ary0 = EQ
fmapAry0RS :: (a -> b) -> Ary0 a -> Ary0 b
fmapAry0RS _ = coerce
mk_eq' ''Ary0 [| \ _ _ -> True |]
inspect $ 'eqAry0RS ==- 'eqAry0S
inspect $ 'eqAry0R ==- 'eqAry0G
mk_compare' ''Ary0 [| \ _ _ -> EQ |]
inspect $ 'compareAry0RS ==- 'compareAry0S
inspect $ 'compareAry0R ==- 'compareAry0G
mk_fmap ''Ary0 [| \ _ _ -> Ary0 |]
inspect $ 'fmapAry0RS ==- 'fmapAry0S
inspect $ 'fmapAry0R ==- 'fmapAry0G
mk_foldMap ''Ary0 [| \ _ _ -> mempty |]
inspect $ 'foldMapAry0R ==- 'foldMapAry0S
inspect $ 'foldMapAry0R ==- 'foldMapAry0G
mk_foldr ''Ary0 [| \_ b _ -> b |]
inspect $ 'foldrAry0R ==- 'foldrAry0S
inspect $ 'foldrAry0R ==- 'foldrAry0G
mk_traverse ''Ary0 [| \ _ _ -> pure Ary0 |]
inspect $ 'traverseAry0S ==- 'traverseAry0S
inspect $ 'traverseAry0R ==- 'traverseAry0G
mk_sequenceA ''Ary0 [| \ _ -> pure Ary0 |]
inspect $ 'sequenceAAry0S ==- 'sequenceAAry0S
inspect $ 'sequenceAAry0R ==- 'sequenceAAry0G
-- Ary1
eqAry1RS :: Eq a => Ary1 a -> Ary1 a -> Bool
eqAry1RS (Ary1 x1) (Ary1 y1) = x1 == y1
compareAry1RS :: Ord a => Ary1 a -> Ary1 a -> Ordering
compareAry1RS (Ary1 x1) (Ary1 y1) = compare x1 y1
fmapAry1RS :: (a -> b) -> Ary1 a -> Ary1 b
fmapAry1RS f (Ary1 x) = Ary1 (f x)
foldMapAry1RS :: Monoid m => (a -> m) -> Ary1 a -> m
foldMapAry1RS f (Ary1 x) = f x
foldrAry1RS :: (a -> b -> b) -> b -> Ary1 a -> b
foldrAry1RS f b (Ary1 x) = f x b
traverseAry1RS :: Applicative f => (a -> f b) -> Ary1 a -> f (Ary1 b)
traverseAry1RS f (Ary1 x) = Ary1 <$> f x
sequenceAAry1RS :: Applicative f => Ary1 (f a) -> f (Ary1 a)
sequenceAAry1RS (Ary1 x) = Ary1 <$> x
mk_eq ''Ary1 [| \ ~(Ary1 x1) ~(Ary1 y1) -> x1 == y1 |]
inspect $ 'eqAry1RS ==- 'eqAry1S
inspect $ 'eqAry1R ==- 'eqAry1G
mk_compare ''Ary1 [| \ ~(Ary1 x1) ~(Ary1 y1) -> compare x1 y1 |]
inspect $ 'compareAry1RS ==- 'compareAry1S
inspect $ 'compareAry1R ==- 'compareAry1G
mk_fmap ''Ary1 [| \ f ~(Ary1 x) -> Ary1 (f x) |]
inspect $ 'fmapAry1RS ==- 'fmapAry1S
inspect $ 'fmapAry1R ==- 'fmapAry1G
mk_foldMap ''Ary1 [| \ f ~(Ary1 x) -> f x |]
inspect $ 'foldMapAry1RS ==- 'foldMapAry1S
inspect $ 'foldMapAry1R ==- 'foldMapAry1G
mk_foldr ''Ary1 [| \ f r ~(Ary1 x) -> f x r |]
inspect $ 'foldrAry1RS ==- 'foldrAry1S
inspect $ 'foldrAry1R ==- 'foldrAry1G
mk_traverse ''Ary1 [| \ f ~(Ary1 x) -> Ary1 <$> f x |]
inspect $ 'traverseAry1RS ==- 'traverseAry1S
inspect $ 'traverseAry1R ==- 'traverseAry1G
mk_sequenceA ''Ary1 [| \ ~(Ary1 x) -> Ary1 <$> x |]
inspect $ 'sequenceAAry1RS ==- 'sequenceAAry1S
inspect $ 'sequenceAAry1R ==- 'sequenceAAry1G
-- Generic @to@ seems to be lazy here
mk_ap ''Ary1 [| \ ~(Ary1 f1) ~(Ary1 x1) -> Ary1 (f1 x1) |]
inspect $ 'apAry1R ==- 'apAry1G
mk_liftA2 ''Ary1 [| \ f ~(Ary1 x1) ~(Ary1 x2) -> Ary1 (f x1 x2) |]
inspect $ 'liftA2Ary1R ==- 'liftA2Ary1G
-- Ary1' (strict, this is entirely the same as Ary1)
eqAry1'RS :: Eq a => Ary1' a -> Ary1' a -> Bool
eqAry1'RS (Ary1' x1) (Ary1' y1) = x1 == y1
compareAry1'RS :: Ord a => Ary1' a -> Ary1' a -> Ordering
compareAry1'RS (Ary1' x1) (Ary1' y1) = compare x1 y1
fmapAry1'RS :: (a -> b) -> Ary1' a -> Ary1' b
fmapAry1'RS f (Ary1' x) = Ary1' (f x)
foldMapAry1'RS :: Monoid m => (a -> m) -> Ary1' a -> m
foldMapAry1'RS f (Ary1' x) = f x
foldrAry1'RS :: (a -> b -> b) -> b -> Ary1' a -> b
foldrAry1'RS f b (Ary1' x) = f x b
traverseAry1'RS :: Applicative f => (a -> f b) -> Ary1' a -> f (Ary1' b)
traverseAry1'RS f (Ary1' x) = Ary1' <$> f x
sequenceAAry1'RS :: Applicative f => Ary1' (f a) -> f (Ary1' a)
sequenceAAry1'RS (Ary1' x) = Ary1' <$> x
mk_eq ''Ary1' [| \ ~(Ary1' x1) ~(Ary1' y1) -> x1 == y1 |]
inspect $ 'eqAry1'RS ==- 'eqAry1'S
inspect $ 'eqAry1'R ==- 'eqAry1'G
mk_compare ''Ary1' [| \ ~(Ary1' x1) ~(Ary1' y1) -> compare x1 y1 |]
inspect $ 'compareAry1'RS ==- 'compareAry1'S
inspect $ 'compareAry1'R ==- 'compareAry1'G
mk_fmap ''Ary1' [| \ f ~(Ary1' x) -> Ary1' (f x) |]
inspect $ 'fmapAry1'RS ==- 'fmapAry1'S
inspect $ 'fmapAry1'R ==- 'fmapAry1'G
mk_foldMap ''Ary1' [| \ f ~(Ary1' x) -> f x |]
inspect $ 'foldMapAry1'RS ==- 'foldMapAry1'S
inspect $ 'foldMapAry1'R ==- 'foldMapAry1'G
mk_foldr ''Ary1' [| \ f r ~(Ary1' x) -> f x r |]
inspect $ 'foldrAry1'RS ==- 'foldrAry1'S
inspect $ 'foldrAry1'R ==- 'foldrAry1'G
-- TODO: These tests fail because of a difference in how the Functor
-- dictionary is accessed via the Applicative dictionary.
-- The rest looks alright.
#if __GLASGOW_HASKELL__ >= 810
mk_traverse ''Ary1' [| \ f ~(Ary1' x) -> Ary1' <$> f x |]
inspect $ 'traverseAry1'RS ==- 'traverseAry1'S
inspect $ 'traverseAry1'R ==- 'traverseAry1'G
mk_sequenceA ''Ary1' [| \ ~(Ary1' x) -> Ary1' <$> x |]
inspect $ 'sequenceAAry1'RS ==- 'sequenceAAry1'S
inspect $ 'sequenceAAry1'R ==- 'sequenceAAry1'G
#endif
-- Generic @to@ seems to be lazy here
mk_ap ''Ary1' [| \ ~(Ary1' f1) ~(Ary1' x1) -> Ary1' (f1 x1) |]
inspect $ 'apAry1'R ==- 'apAry1'G
mk_liftA2 ''Ary1' [| \ f ~(Ary1' x1) ~(Ary1' x2) -> Ary1' (f x1 x2) |]
inspect $ 'liftA2Ary1'R ==- 'liftA2Ary1'G
-- Ary1NT
eqAry1NTRS :: Eq a => Ary1NT a -> Ary1NT a -> Bool
eqAry1NTRS = (coerce :: (a -> a -> Bool) -> Ary1NT a -> Ary1NT a -> Bool) (==)
compareAry1NTRS :: Ord a => Ary1NT a -> Ary1NT a -> Ordering
compareAry1NTRS = (coerce :: (a -> a -> Ordering) -> Ary1NT a -> Ary1NT a -> Ordering) compare
mk_eq ''Ary1NT [| \ (Ary1NT x1) (Ary1NT y1) -> x1 == y1 |]
inspect $ 'eqAry1NTRS ==- 'eqAry1NTS
inspect $ 'eqAry1NTR ==- 'eqAry1NTG
mk_compare ''Ary1NT [| \ (Ary1NT x1) (Ary1NT y1) -> compare x1 y1 |]
inspect $ 'compareAry1NTRS ==- 'compareAry1NTS
inspect $ 'compareAry1NTR ==- 'compareAry1NTG
mk_fmap ''Ary1NT [| \ f (Ary1NT x) -> Ary1NT (f x) |]
inspect $ 'fmapAry1NTR ==- 'fmapAry1NTS
inspect $ 'fmapAry1NTR ==- 'fmapAry1NTG
mk_foldMap ''Ary1NT [| \ f (Ary1NT x) -> f x |]
inspect $ 'foldMapAry1NTR ==- 'foldMapAry1NTS
inspect $ 'foldMapAry1NTR ==- 'foldMapAry1NTG
mk_foldr ''Ary1NT [| \ f r (Ary1NT x) -> f x r |]
inspect $ 'foldrAry1NTR ==- 'foldrAry1NTS
inspect $ 'foldrAry1NTR ==- 'foldrAry1NTG
mk_traverse ''Ary1NT [| \ f (Ary1NT x) -> fmap Ary1NT (f x) |]
inspect $ 'traverseAry1NTR ==- 'traverseAry1NTS
inspect $ 'traverseAry1NTR ==- 'traverseAry1NTG
mk_ap ''Ary1NT [| \ (Ary1NT f1) (Ary1NT x1) -> Ary1NT (f1 x1) |]
inspect $ 'apAry1NTR ==- 'apAry1NTG
mk_liftA2 ''Ary1NT [| \ f (Ary1NT x1) (Ary1NT x2) -> Ary1NT (f x1 x2) |]
inspect $ 'liftA2Ary1NTR ==- 'liftA2Ary1NTG
-- Ary2
mk_eq ''Ary2 [| \ (Ary2 x1 x2) (Ary2 y1 y2) -> x1 == y1 && x2 == y2 |]
inspect $ 'eqAry2R ==- 'eqAry2S
inspect $ 'eqAry2R ==- 'eqAry2G
mk_compare ''Ary2 [| \ (Ary2 x1 x2) (Ary2 y1 y2) -> compare x1 y1 <> compare x2 y2 |]
inspect $ 'compareAry2R ==- 'compareAry2S
inspect $ 'compareAry2R ==- 'compareAry2G
mk_fmap ''Ary2 [| \ f (Ary2 x y) -> Ary2 (f x) (f y) |]
inspect $ 'fmapAry2R ==- 'fmapAry2S
inspect $ 'fmapAry2R ==- 'fmapAry2G
mk_foldMap ''Ary2 [| \ f (Ary2 x y) -> f x `mappend` f y |]
inspect $ 'foldMapAry2R ==- 'foldMapAry2S
inspect $ 'foldMapAry2R ==- 'foldMapAry2G
mk_foldr ''Ary2 [| \ f r (Ary2 x y) -> f x (f y r) |]
inspect $ 'foldrAry2R ==- 'foldrAry2S
inspect $ 'foldrAry2R ==- 'foldrAry2G
mk_traverse ''Ary2 [| \ f (Ary2 x y) -> liftA2 Ary2 (f x) (f y) |]
inspect $ 'traverseAry2R ==- 'traverseAry2S
inspect $ 'traverseAry2R ==- 'traverseAry2G
mk_sequenceA ''Ary2 [| \ (Ary2 x y) -> liftA2 Ary2 x y |]
inspect $ 'sequenceAAry2R ==- 'sequenceAAry2S
inspect $ 'sequenceAAry2R ==- 'sequenceAAry2G
mk_ap ''Ary2 [| \ (Ary2 f1 f2) (Ary2 x1 x2) -> Ary2 (f1 x1) (f2 x2) |]
inspect $ 'apAry2R ==- 'apAry2G
mk_liftA2 ''Ary2 [| \ f (Ary2 x1 y1) (Ary2 x2 y2) -> Ary2 (f x1 x2) (f y1 y2) |]
inspect $ 'liftA2Ary2R ==- 'liftA2Ary2G
-- Ary4
sequenceAAry4RS :: Applicative f => Ary4 (f a) -> f (Ary4 a)
sequenceAAry4RS = traverse id
-- The simplifier is good enough to reassociate (&&)
mk_eq ''Ary4
[| \ (Ary4 x1 x2 x3 x4) (Ary4 y1 y2 y3 y4) ->
x1 == y1 && x2 == y2 && x3 == y3 && x4 == y4 |]
inspect $ 'eqAry4R ==- 'eqAry4S
inspect $ 'eqAry4R ==- 'eqAry4G
-- The simplifier is good enough to reassociate (<>)
mk_compare ''Ary4
[| \ (Ary4 x1 x2 x3 x4) (Ary4 y1 y2 y3 y4) ->
compare x1 y1 <> compare x2 y2 <> compare x3 y3 <> compare x4 y4 |]
inspect $ 'compareAry4R ==- 'compareAry4S
inspect $ 'compareAry4R ==- 'compareAry4G
mk_fmap ''Ary4
[| \ f (Ary4 x y z t) -> Ary4 (f x) (f y) z (fmap f t) |]
inspect $ 'fmapAry4R ==- 'fmapAry4S
inspect $ 'fmapAry4R ==- 'fmapAry4G
mk_foldMap ''Ary4
[| \ f (Ary4 x y _ z) -> f x `mappend` (f y `mappend` foldMap f z) |]
inspect $ 'foldMapAry4R ==- 'foldMapAry4S
inspect $ 'foldMapAry4R ==- 'foldMapAry4G
mk_foldr ''Ary4
[| \ f r (Ary4 x y _ t) -> f x (f y (foldr f r t)) |]
inspect $ 'foldrAry4R ==- 'foldrAry4S
inspect $ 'foldrAry4R ==- 'foldrAry4G
mk_traverse ''Ary4
[| \ f (Ary4 x y z t) ->
liftA2 (\x' y' -> Ary4 x' y' z) (f x) (f y) <*> traverse f t |]
inspect $ 'traverseAry4R ==- 'traverseAry4S
inspect $ 'traverseAry4R ==- 'traverseAry4G
mk_sequenceA ''Ary4 [| \ (Ary4 x y z t) -> liftA2 (\x' y' -> Ary4 x' y' z) x y <*> sequenceA t |]
inspect $ 'sequenceAAry4RS ==- 'sequenceAAry4S
inspect $ 'sequenceAAry4R ==- 'sequenceAAry4G
mk_ap ''Ary4
[| \ (Ary4 f1 f2 fz f3) (Ary4 x1 x2 xz x3) ->
Ary4 (f1 x1) (f2 x2) (fz <> xz) (f3 <*> x3) |]
inspect $ 'apAry4R ==- 'apAry4G
mk_liftA2 ''Ary4
[| \ f (Ary4 x1 y1 fz z1) (Ary4 x2 y2 xz z2) ->
Ary4 (f x1 x2) (f y1 y2) (fz <> xz) (liftA2 f z1 z2) |]
inspect $ 'liftA2Ary4R ==- 'liftA2Ary4G
-- Big
-- The simplifier is good enough to reassociate (&&)
mk_eq ''Big
[| \ x y -> case (x, y) of
(Big0, Big0) -> True
(Big1 x1, Big1 y1) ->
x1 == y1
(Big2 x1 x2, Big2 y1 y2) ->
x1 == y1 && x2 == y2
(Big4 x1 x2 x3 x4, Big4 y1 y2 y3 y4) ->
x1 == y1 && x2 == y2 && x3 == y3 && x4 == y4
(Big8 x1 x2 x3 x4 x5 x6 x7 x8, Big8 y1 y2 y3 y4 y5 y6 y7 y8) ->
x1 == y1 && x2 == y2 && x3 == y3 && x4 == y4 &&
x5 == y5 && x6 == y6 && x7 == y7 && x8 == y8
(_, _) -> False |]
inspect $ 'eqBigR === 'eqBigS
inspect $ 'eqBigR =/= 'eqBigG -- TODO make this test pass
{- TODO Update the rest, after figuring out the above test case
-- The simplifier is good enough to reassociate (<>)
mk_compare ''Big
[| \ (Big4 x1 x2 x3 x4) (Big4 y1 y2 y3 y4) ->
compare x1 y1 <> compare x2 y2 <> compare x3 y3 <> compare x4 y4 |]
inspect $ 'compareBigR === 'compareBigS
inspect $ 'compareBigR === 'compareBigG
mk_fmap ''Big
[| \ f (Big4 x y z t) -> Big (f x) (f y) z (fmap f t) |]
inspect $ 'fmapBigR ==- 'fmapBigS
inspect $ 'fmapBigR ==- 'fmapBigG
mk_foldMap ''Big
[| \ f (Big4 x y _ z) -> f x `mappend` (f y `mappend` foldMap f z) |]
inspect $ 'foldMapBigR ==- 'foldMapBigS
inspect $ 'foldMapBigR ==- 'foldMapBigG
mk_foldr ''Big
[| \ f r (Big4 x y _ t) -> f x (f y (foldr f r t)) |]
inspect $ 'foldrBigR ==- 'foldrBigS
inspect $ 'foldrBigR ==- 'foldrBigG
mk_traverse ''Big
[| \ f (Big4 x y z t) ->
liftA2 (\x' y' -> Big x' y' z) (f x) (f y) <*> (traverse f t) |]
inspect $ 'traverseBigR ==- 'traverseBigS
inspect $ 'traverseBigR ==- 'traverseBigG
mk_sequenceA ''Big [| \ (Big4 x y z t) -> liftA2 (\x' y' -> Big x' y' z) x y <*> sequenceA t |]
inspect $ 'sequenceABigRS ==- 'sequenceABigS
inspect $ 'sequenceABigR ==- 'sequenceABigG
mk_ap ''Big
[| \ (Big4 f1 f2 fz f3) (Big4 x1 x2 xz x3) ->
Big (f1 x1) (f2 x2) (fz <> xz) (f3 <*> x3) |]
inspect $ 'apBigR ==- 'apBigG
mk_liftA2 ''Big
[| \ f (Big4 x1 y1 fz z1) (Big4 x2 y2 xz z2) ->
Big (f x1 x2) (f y1 y2) (fz <> xz) (liftA2 f z1 z2) |]
inspect $ 'liftA2BigR ==- 'liftA2BigG
-}
-- dummy
main :: IO ()
main = pure ()
|