@@ -139,12 +139,18 @@ tests =
139
139
[ testProperty " Reference vs IO" prop_stm_referenceIO
140
140
, testProperty " Reference vs Sim" prop_stm_referenceSim
141
141
]
142
- , testGroup " MonadFix instance"
143
- [ testProperty " purity" prop_mfix_purity
144
- , testProperty " purity2" prop_mfix_purity_2
145
- , testProperty " tightening" prop_mfix_left_shrinking
146
- , testProperty " lazy" prop_mfix_lazy
147
- , testProperty " recdata" prop_mfix_recdata
142
+ , testGroup " MonadFix instances"
143
+ [ testGroup " IOSim"
144
+ [ testProperty " purity" prop_mfix_purity_IOSim
145
+ , testProperty " purity2" prop_mfix_purity_2
146
+ , testProperty " tightening" prop_mfix_left_shrinking_IOSim
147
+ , testProperty " lazy" prop_mfix_lazy
148
+ , testProperty " recdata" prop_mfix_recdata
149
+ ]
150
+ , testGroup " STM"
151
+ [ testProperty " purity" prop_mfix_purity_STM
152
+ , testProperty " tightening" prop_mfix_left_shrinking_STM
153
+ ]
148
154
]
149
155
-- NOTE: Most of the tests below only work because the io-sim
150
156
-- scheduler works the way it does.
@@ -592,15 +598,18 @@ test_wakeup_order = do
592
598
593
599
-- | Purity demands that @mfix (return . f) = return (fix f)@.
594
600
--
595
- prop_mfix_purity :: Positive Int -> Bool
596
- prop_mfix_purity (Positive n) =
597
- runSimOrThrow
598
- (mfix (return . factorial)) n
599
- == fix factorial n
601
+ prop_mfix_purity_m :: forall m . MonadFix m => Positive Int -> m Bool
602
+ prop_mfix_purity_m (Positive n) =
603
+ (== fix factorial n) . ($ n) <$> mfix (return . factorial)
600
604
where
601
605
factorial :: (Int -> Int ) -> Int -> Int
602
606
factorial = \ rec_ k -> if k <= 1 then 1 else k * rec_ (k - 1 )
603
607
608
+ prop_mfix_purity_IOSim :: Positive Int -> Bool
609
+ prop_mfix_purity_IOSim a = runSimOrThrow $ prop_mfix_purity_m a
610
+
611
+ prop_mfix_purity_STM :: Positive Int -> Bool
612
+ prop_mfix_purity_STM a = runSimOrThrow $ atomically $ prop_mfix_purity_m a
604
613
605
614
prop_mfix_purity_2 :: [Positive Int ] -> Bool
606
615
prop_mfix_purity_2 as =
@@ -634,12 +643,12 @@ prop_mfix_purity_2 as =
634
643
(realToFrac `map` as')
635
644
636
645
637
- prop_mfix_left_shrinking
646
+ prop_mfix_left_shrinking_IOSim
638
647
:: Int
639
648
-> NonNegative Int
640
649
-> Positive Int
641
650
-> Bool
642
- prop_mfix_left_shrinking n (NonNegative d) (Positive i) =
651
+ prop_mfix_left_shrinking_IOSim n (NonNegative d) (Positive i) =
643
652
let mn :: IOSim s Int
644
653
mn = do say " "
645
654
threadDelay (realToFrac d)
@@ -657,6 +666,25 @@ prop_mfix_left_shrinking n (NonNegative d) (Positive i) =
657
666
threadDelay (realToFrac d) $> a : rec_)))
658
667
659
668
669
+ prop_mfix_left_shrinking_STM
670
+ :: Int
671
+ -> Positive Int
672
+ -> Bool
673
+ prop_mfix_left_shrinking_STM n (Positive i) =
674
+ let mn :: STMSim s Int
675
+ mn = do say " "
676
+ return n
677
+ in
678
+ take i
679
+ (runSimOrThrow $ atomically $
680
+ mfix (\ rec_ -> mn >>= \ a -> return $ a : rec_))
681
+ ==
682
+ take i
683
+ (runSimOrThrow $ atomically $
684
+ mn >>= \ a ->
685
+ (mfix (\ rec_ -> return $ a : rec_)))
686
+
687
+
660
688
661
689
-- | 'Example 8.2.1' in 'Value Recursion in Monadic Computations'
662
690
-- <https://leventerkok.github.io/papers/erkok-thesis.pdf>
@@ -756,7 +784,7 @@ probeOutput probe x = atomically (modifyTVar probe (x:))
756
784
757
785
758
786
--
759
- -- Syncronous exceptions
787
+ -- Synchronous exceptions
760
788
--
761
789
762
790
unit_catch_0, unit_catch_1, unit_catch_2, unit_catch_3, unit_catch_4,
0 commit comments