integer-types 0.1.2.0 → 0.1.3.0
raw patch · 11 files changed
+329/−130 lines, 11 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Integer: class Increase a
+ Integer: class StrictlyIncrease a
+ Integer: increase :: Increase a => Natural -> a -> a
+ Integer: strictlyIncrease :: StrictlyIncrease a => Positive -> a -> a
+ Integer.Increase: class Increase a
+ Integer.Increase: increase :: Increase a => Natural -> a -> a
+ Integer.Increase: instance Integer.Increase.Increase GHC.Num.Integer.Integer
+ Integer.Increase: instance Integer.Increase.Increase GHC.Num.Natural.Natural
+ Integer.Increase: instance Integer.Increase.Increase Integer.Positive.Unsafe.Positive
+ Integer.Increase: instance Integer.Increase.Increase Integer.Signed.Signed
+ Integer.Integer: increase :: Natural -> Integer -> Integer
+ Integer.Integer: strictlyIncrease :: Positive -> Integer -> Integer
+ Integer.Natural: strictlyIncrease :: Positive -> Natural -> Natural
+ Integer.Positive: increase :: Natural -> Positive -> Positive
+ Integer.Signed: addOne :: Signed -> Signed
+ Integer.Signed: increase :: Natural -> Signed -> Signed
+ Integer.Signed: one :: Signed
+ Integer.Signed: strictlyIncrease :: Positive -> Signed -> Signed
+ Integer.Signed: subtractOne :: Signed -> Signed
+ Integer.StrictlyIncrease: class StrictlyIncrease a
+ Integer.StrictlyIncrease: instance Integer.StrictlyIncrease.StrictlyIncrease GHC.Num.Integer.Integer
+ Integer.StrictlyIncrease: instance Integer.StrictlyIncrease.StrictlyIncrease GHC.Num.Natural.Natural
+ Integer.StrictlyIncrease: instance Integer.StrictlyIncrease.StrictlyIncrease Integer.Positive.Unsafe.Positive
+ Integer.StrictlyIncrease: instance Integer.StrictlyIncrease.StrictlyIncrease Integer.Signed.Signed
+ Integer.StrictlyIncrease: strictlyIncrease :: StrictlyIncrease a => Positive -> a -> a
Files
- changelog.md +16/−0
- integer-types.cabal +3/−1
- library/Integer.hs +6/−0
- library/Integer/Increase.hs +27/−0
- library/Integer/Integer.hs +12/−0
- library/Integer/Natural.hs +12/−4
- library/Integer/Positive.hs +10/−5
- library/Integer/Positive/Unsafe.hs +13/−4
- library/Integer/Signed.hs +38/−0
- library/Integer/StrictlyIncrease.hs +27/−0
- test/Main.hs +165/−116
changelog.md view
@@ -1,3 +1,19 @@+## 0.1.3.0 (2023-07-14)++Added modules `Integer.Increase`, `Integer.StrictlyIncrease`++Added classes to the `Integer` module:+`Increase (increase)`, `StrictlyIncrease (strictlyIncrease)`++Added to the `Integer.Integer` module: `increase`, `strictlyIncrease`++Added to the `Integer.Natural` module: `strictlyIncrease`++Added to the `Integer.Positive` module: `increase`++Added to the `Integer.Signed` module: `increase`, `strictlyIncrease`,+`one`, `addOne`, `subtractOne`+ ## 0.1.2.0 (2023-06-26) Add `Read` instance for `Positive`
integer-types.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0 name: integer-types-version: 0.1.2.0+version: 0.1.3.0 category: Numeric synopsis: Integer, Natural, and Positive@@ -46,11 +46,13 @@ Integer.BoundedBelow Integer.Conversion Integer.Finite+ Integer.Increase Integer.Integer Integer.Natural Integer.Positive Integer.Sign Integer.Signed+ Integer.StrictlyIncrease Integer.Subtraction other-modules: Integer.Positive.Unsafe
library/Integer.hs view
@@ -6,6 +6,10 @@ Signed (Zero, NonZero, Minus, Plus), Sign (MinusSign, PlusSign), + -- ** Addition+ Increase (increase),+ StrictlyIncrease (strictlyIncrease),+ -- ** Subtraction Subtraction (subtractInteger, subtractSigned), Subtraction' (subtract),@@ -34,11 +38,13 @@ ( ConvertWithFinite (fromInt, fromWord, toInt, toWord), Finite (..), )+import Integer.Increase (Increase (increase)) import Integer.Integer (Integer) import Integer.Natural (Natural) import Integer.Positive (Positive) import Integer.Sign (Sign (MinusSign, PlusSign)) import Integer.Signed (Signed (Minus, NonZero, Plus, Zero))+import Integer.StrictlyIncrease (StrictlyIncrease (strictlyIncrease)) import Integer.Subtraction ( Subtraction (subtractInteger, subtractSigned), Subtraction' (subtract),
+ library/Integer/Increase.hs view
@@ -0,0 +1,27 @@+module Integer.Increase where++import Integer.Integer (Integer)+import Integer.Integer qualified as Integer+import Integer.Natural (Natural)+import Integer.Positive (Positive)+import Integer.Positive qualified as Positive+import Integer.Signed (Signed)+import Integer.Signed qualified as Signed+import Prelude qualified as Num (Num (..))++-- | Class of numbers are closed under addition with 'Natural'+class Increase a where+ -- | Addition+ increase :: Natural -> a -> a++instance Increase Integer where+ increase = Integer.increase++instance Increase Signed where+ increase = Signed.increase++instance Increase Natural where+ increase = (Num.+)++instance Increase Positive where+ increase = Positive.increase
library/Integer/Integer.hs view
@@ -23,6 +23,12 @@ -- ** Word toWord, fromWord,++ -- * Arithmetic++ -- ** Increase+ increase,+ strictlyIncrease, ) where @@ -78,3 +84,9 @@ fromWord :: Word -> Integer fromWord = Num.toInteger++increase :: Natural -> Integer -> Integer+increase n = (Num.+) (fromNatural n)++strictlyIncrease :: Positive -> Integer -> Integer+strictlyIncrease n = (Num.+) (fromPositive n)
library/Integer/Natural.hs view
@@ -2,9 +2,6 @@ ( -- * Type Natural, - -- * Subtraction- subtract,- -- * Conversion -- ** Positive@@ -27,7 +24,15 @@ toWord, fromWord, - -- * One (1)+ -- * Arithmetic++ -- ** Subtraction+ subtract,++ -- ** Increase+ strictlyIncrease,++ -- ** One (1) one, addOne, subtractOne,@@ -110,3 +115,6 @@ length :: [a] -> Natural length = List.foldl' (\x _ -> x Num.+ 1) 0++strictlyIncrease :: Positive -> Natural -> Natural+strictlyIncrease p n = Positive.toNatural p Num.+ n
library/Integer/Positive.hs view
@@ -2,9 +2,6 @@ ( -- * Type Positive, - -- * Subtraction- subtract,- -- * Conversion -- ** Natural@@ -27,7 +24,15 @@ toWord, fromWord, - -- * One (1)+ -- * Arithmetic++ -- ** Subtraction+ subtract,++ -- ** Increase+ increase,++ -- ** One (1) one, addOne, subtractOne,@@ -43,7 +48,7 @@ import Data.Ord qualified as Ord import Data.Word (Word) import Essentials-import Integer.Positive.Unsafe (Positive, addOne, one, toInteger, toNatural)+import Integer.Positive.Unsafe (Positive, addOne, increase, one, toInteger, toNatural) import Integer.Positive.Unsafe qualified as Unsafe import Integer.Signed (Signed (..)) import Numeric.Natural (Natural)
library/Integer/Positive/Unsafe.hs view
@@ -25,10 +25,15 @@ fromIntChecked, -- * Arithmetic++ -- ** Subtraction subtract, subtractChecked, - -- * One (1)+ -- ** Increase+ increase,++ -- ** One (1) one, addOne, subtractOne,@@ -103,6 +108,9 @@ subtractOneChecked :: Positive -> Positive subtractOneChecked x = case x of 1 -> Exception.throw Exception.Underflow; _ -> subtractOne x +increase :: Natural -> Positive -> Positive+increase n = fromNatural . (Num.+ n) . toNatural+ toInt :: Positive -> Int toInt = Num.fromIntegral . toNatural @@ -185,9 +193,10 @@ instance Read Positive where readsPrec i = do xs <- Read.readsPrec @Natural i- pure $ xs & Maybe.mapMaybe \case- (0, _) -> Nothing- (n, s) -> Just (fromNatural n, s)+ pure $+ xs & Maybe.mapMaybe \case+ (0, _) -> Nothing+ (n, s) -> Just (fromNatural n, s) readPrec = do n <- Read.readPrec @Natural if n == 0 then fail "0" else pure $ fromNatural n
library/Integer/Signed.hs view
@@ -23,6 +23,17 @@ -- ** Word toWord, fromWord,++ -- * Arithmetic++ -- ** Increase+ increase,+ strictlyIncrease,++ -- ** One (1)+ one,+ addOne,+ subtractOne, ) where @@ -107,6 +118,33 @@ toNatural (Minus _) = Nothing toNatural Zero = Just 0 toNatural (Plus x) = Just (Positive.Unsafe.toNatural x)++one :: Signed+one = Plus Positive.Unsafe.one++addOne :: Signed -> Signed+addOne Zero = one+addOne (Minus 1) = Zero+addOne (Minus n) = Minus (Positive.Unsafe.subtractOne n)+addOne (Plus n) = Plus (Positive.Unsafe.addOne n)++subtractOne :: Signed -> Signed+subtractOne Zero = Minus 1+subtractOne (Plus 1) = Zero+subtractOne (Plus n) = Plus (Positive.Unsafe.subtractOne n)+subtractOne (Minus n) = Minus (Positive.Unsafe.addOne n)++increase :: Natural -> Signed -> Signed+increase 0 x = x+increase n x = strictlyIncrease (Positive.Unsafe.fromNatural n) x++strictlyIncrease :: Positive -> Signed -> Signed+strictlyIncrease a Zero = Plus a+strictlyIncrease a (Plus b) = Plus ((Num.+) a b)+strictlyIncrease a (Minus b) = case Ord.compare a b of+ Ord.EQ -> Zero+ Ord.LT -> Minus $ Positive.Unsafe.subtract b a+ Ord.GT -> Plus $ Positive.Unsafe.subtract a b add :: Signed -> Signed -> Signed add Zero x = x
+ library/Integer/StrictlyIncrease.hs view
@@ -0,0 +1,27 @@+module Integer.StrictlyIncrease where++import Integer.Integer (Integer)+import Integer.Integer qualified as Integer+import Integer.Natural (Natural)+import Integer.Natural qualified as Natural+import Integer.Positive (Positive)+import Integer.Signed (Signed)+import Integer.Signed qualified as Signed+import Prelude qualified as Num (Num (..))++-- | Class of numbers that are closed under addition with 'Positive'+class StrictlyIncrease a where+ -- | Addition+ strictlyIncrease :: Positive -> a -> a++instance StrictlyIncrease Integer where+ strictlyIncrease = Integer.strictlyIncrease++instance StrictlyIncrease Signed where+ strictlyIncrease = Signed.strictlyIncrease++instance StrictlyIncrease Natural where+ strictlyIncrease = Natural.strictlyIncrease++instance StrictlyIncrease Positive where+ strictlyIncrease = (Num.+)
test/Main.hs view
@@ -19,24 +19,39 @@ import Integer.Gen qualified as Gen import Integer.Natural qualified as Natural import Integer.Positive qualified as Positive+import Integer.Signed qualified as Signed import System.IO (IO)-import Test.Hspec (describe, hspec, it, shouldBe)-import Test.Hspec.Hedgehog- ( evalMaybe,- hedgehog,- modifyMaxSuccess,- (===),- )+import Test.Hspec (context, hspec, it, shouldBe)+import Test.Hspec.Hedgehog (evalMaybe, hedgehog, modifyMaxSuccess, (===)) import Prelude (Num, fromInteger, toInteger, ($!), (*), (+), (-)) import Prelude qualified as Bounded (Bounded (..)) import Prelude qualified as Num (fromInteger, toInteger) main :: IO () main = hspec do- describe- "Closed Num operations op behaves the same in A \- \as in Integer"- $ modifyMaxSuccess (\_ -> 1000) do+ context "addOne in A behaves the same as (+ 1) in Integer" do+ modifyMaxSuccess (\_ -> 1000) do+ it "A = Natural" $ hedgehog do+ x :: Natural <- Hedgehog.forAll Gen.integral+ toInteger (Natural.addOne x) === toInteger x + 1+ it "A = Positive" $ hedgehog do+ x :: Positive <- Hedgehog.forAll Gen.integral+ toInteger (Positive.addOne x) === toInteger x + 1+ it "A = Signed" $ hedgehog do+ x :: Signed <- Hedgehog.forAll Gen.integral+ toInteger (Signed.addOne x) === toInteger x + 1++ context "subtractOne in A behaves the same as (- 1) in Integer" do+ modifyMaxSuccess (\_ -> 1000) do+ it "A = Positive" $ hedgehog do+ x :: Positive <- Hedgehog.forAll Gen.integral+ toInteger (Positive.subtractOne x) === toInteger x - 1+ it "A = Signed" $ hedgehog do+ x :: Signed <- Hedgehog.forAll Gen.integral+ toInteger (Signed.subtractOne x) === toInteger x - 1++ context "Closed Num operations op behaves the same in A as in Integer" do+ modifyMaxSuccess (\_ -> 1000) do let check :: forall a m. GenIntegral a =>@@ -53,9 +68,8 @@ it "op = (*), A = Positive" $ hedgehog $ check @Positive (*) it "op = (*), A = Signed" $ hedgehog $ check @Signed (*) - describe- "subtract in A behaves the same as (-) in B"- $ modifyMaxSuccess (\_ -> 1000) do+ context "subtract in A behaves the same as (-) in B" do+ modifyMaxSuccess (\_ -> 1000) do let check :: forall a b m. (GenIntegral a, Subtraction a, Subtraction' b, Num b) =>@@ -73,10 +87,8 @@ it "A = Positive, B = Signed" $ hedgehog $ check @Positive @Signed it "A = Positive, B = Integer" $ hedgehog $ check @Positive @Integer - describe- "(-) in A behaves the same as (-) in Integer if the result \- \is in A, undefined otherwise"- $ modifyMaxSuccess (\_ -> 1000) do+ context "(-) in A behaves the same as (-) in Integer if the result is in A, undefined otherwise" do+ modifyMaxSuccess (\_ -> 1000) do let check :: forall a m. (GenIntegral a, Subtraction a, IntegerNarrow Integer a) =>@@ -93,7 +105,41 @@ it "A = Positive" $ hedgehog $ check @Positive - describe "convert (convert x) = x" do+ context "increase in A behaves the same as (+) in Integer" do+ modifyMaxSuccess (\_ -> 1000) do+ let check ::+ forall a m.+ (GenIntegral a, Increase a) =>+ Exception.MonadCatch m =>+ Hedgehog.PropertyT m ()+ check = do+ x :: Natural <- Hedgehog.forAll Gen.integral+ y :: a <- Hedgehog.forAll Gen.integral+ toInteger (increase x y) === toInteger x + toInteger y++ it "A = Natural" $ hedgehog $ check @Natural+ it "A = Integer" $ hedgehog $ check @Integer+ it "A = Positive" $ hedgehog $ check @Positive+ it "A = Signed" $ hedgehog $ check @Signed++ context "strictlyIncrease in A behaves the same as (+) in Integer" do+ modifyMaxSuccess (\_ -> 1000) do+ let check ::+ forall a m.+ (GenIntegral a, StrictlyIncrease a) =>+ Exception.MonadCatch m =>+ Hedgehog.PropertyT m ()+ check = do+ x :: Positive <- Hedgehog.forAll Gen.integral+ y :: a <- Hedgehog.forAll Gen.integral+ toInteger (strictlyIncrease x y) === toInteger x + toInteger y++ it "A = Natural" $ hedgehog $ check @Natural+ it "A = Integer" $ hedgehog $ check @Integer+ it "A = Positive" $ hedgehog $ check @Positive+ it "A = Signed" $ hedgehog $ check @Signed++ context "convert (convert x) = x" do let check :: forall a b m. (GenIntegral a, IntegerEquiv a b) =>@@ -106,26 +152,25 @@ it "A = Integer, B = Signed" $ hedgehog $ check @Integer @Signed it "A = Signed, B = Integer" $ hedgehog $ check @Signed @Integer - describe "narrow (convert x) = Just x" $ modifyMaxSuccess (\_ -> 1000) do- let check ::- forall a b m.- (GenIntegral a, IntegerConvert a b, IntegerNarrow b a) =>- Monad m =>- Hedgehog.PropertyT m ()- check = do- x :: a <- Hedgehog.forAll Gen.integral- narrow (convert x :: b) === Just x+ context "narrow (convert x) = Just x" do+ modifyMaxSuccess (\_ -> 1000) do+ let check ::+ forall a b m.+ (GenIntegral a, IntegerConvert a b, IntegerNarrow b a) =>+ Monad m =>+ Hedgehog.PropertyT m ()+ check = do+ x :: a <- Hedgehog.forAll Gen.integral+ narrow (convert x :: b) === Just x - it "A = Natural, B = Integer" $ hedgehog $ check @Natural @Integer- it "A = Natural, B = Signed" $ hedgehog $ check @Natural @Signed- it "A = Positive, B = Integer" $ hedgehog $ check @Positive @Integer- it "A = Positive, B = Signed" $ hedgehog $ check @Positive @Signed- it "A = Positive, B = Natural" $ hedgehog $ check @Positive @Natural+ it "A = Natural, B = Integer" $ hedgehog $ check @Natural @Integer+ it "A = Natural, B = Signed" $ hedgehog $ check @Natural @Signed+ it "A = Positive, B = Integer" $ hedgehog $ check @Positive @Integer+ it "A = Positive, B = Signed" $ hedgehog $ check @Positive @Signed+ it "A = Positive, B = Natural" $ hedgehog $ check @Positive @Natural - describe- "narrow x = (Just y | convert y = x) \- \or Nothing"- $ modifyMaxSuccess (\_ -> 1000) do+ context "narrow x = (Just y | convert y = x) or Nothing" do+ modifyMaxSuccess (\_ -> 1000) do let check :: forall a b m. (GenIntegral a, BoundedBelow b) =>@@ -148,7 +193,7 @@ it "A = Signed, B = Positive" $ hedgehog $ check @Signed @Positive it "A = Natural, B = Positive" $ hedgehog $ check @Natural @Positive - describe "yolo (yolo x) = x, if Integer x is in range of A" do+ context "yolo (yolo x) = x, if Integer x is in range of A" do let check :: forall a m. (GenIntegral a, BoundedBelow a) =>@@ -166,10 +211,8 @@ it "A = Positive" $ hedgehog $ check @Positive it "A = Natural " $ hedgehog $ check @Natural - describe- "toFinite x = (Just y | fromInteger y = x) \- \or Nothing"- $ modifyMaxSuccess (\_ -> 1000) do+ context "toFinite x = (Just y | fromInteger y = x) or Nothing" $+ modifyMaxSuccess (\_ -> 1000) do let check :: forall a b m. Monad m =>@@ -194,7 +237,7 @@ it "A = Signed, B = Int " $ hedgehog $ check @Signed @Int it "A = Signed, B = Word" $ hedgehog $ check @Signed @Word - describe "fromFinite x = narrow (toInteger x)" do+ context "fromFinite x = narrow (toInteger x)" do let check :: forall a b m. Monad m =>@@ -214,87 +257,93 @@ it "A = Int, B = Signed " $ hedgehog $ check @Signed @Int it "A = Word, B = Signed" $ hedgehog $ check @Signed @Word - describe "Enum @Positive" $ do- describe "[a ..]" $ do- it "counts upward" $- take 3 [5 :: Positive ..] `shouldBe` [5, 6, 7]- it "can start with 1" $- take 3 [1 :: Positive ..] `shouldBe` [1, 2, 3]+ context "Enum @Positive" do+ let (~>) = shouldBe @[Positive] - describe "[a .. b]" $ do- it "counts upward" $- [5 .. 8 :: Positive] `shouldBe` [5, 6, 7, 8]- it "can start with 1" $- [1 .. 5 :: Positive] `shouldBe` [1, 2, 3, 4, 5]- it "does not count downward" $ do- [8 .. 5 :: Positive] `shouldBe` []- [8 .. 7 :: Positive] `shouldBe` []- it "can return 1 item" $ do- [3 .. 3 :: Positive] `shouldBe` [3]- [1 .. 1 :: Positive] `shouldBe` [1]+ context "[a ..]" do+ it "counts upward" do+ take 3 [5 ..] ~> [5, 6, 7]+ it "can start with 1" do+ take 3 [1 ..] ~> [1, 2, 3] - describe "[a, b ..]" $ do- it "can count upward by 1" $ do- take 5 [5, 6 :: Positive ..] `shouldBe` [5, 6, 7, 8, 9]- take 5 [1, 2 :: Positive ..] `shouldBe` [1, 2, 3, 4, 5]- it "can count downward by 1" $- [5, 4 :: Positive ..] `shouldBe` [5, 4, 3, 2, 1]- it "can count upward by 2" $ do- take 5 [5, 7 :: Positive ..] `shouldBe` [5, 7, 9, 11, 13]- take 5 [1, 3 :: Positive ..] `shouldBe` [1, 3, 5, 7, 9]- it "can count downward by 2" $- [9, 7 :: Positive ..] `shouldBe` [9, 7, 5, 3, 1]- it "can count downward by 2 without exactly reaching its lower bound" $- [8, 6 :: Positive ..] `shouldBe` [8, 6, 4, 2]- it "can repeat 1 item indefinitely" $- take 5 [4, 4 :: Positive ..] `shouldBe` [4, 4, 4, 4, 4]+ context "[a .. b]" do+ it "counts upward" do+ [5 .. 8] ~> [5, 6, 7, 8]+ it "can start with 1" do+ [1 .. 5] ~> [1, 2, 3, 4, 5]+ it "does not count downward" do+ [8 .. 5] ~> []+ [8 .. 7] ~> []+ it "can return 1 item" do+ [3 .. 3] ~> [3]+ [1 .. 1] ~> [1] - describe "[a, b .. c]" $ do- it "can count upward by 1" $ do- [5, 6 .. 9 :: Positive] `shouldBe` [5, 6, 7, 8, 9]- [1, 2 .. 5 :: Positive] `shouldBe` [1, 2, 3, 4, 5]- it "can count downward by 1" $- [9, 8 .. 5 :: Positive] `shouldBe` [9, 8, 7, 6, 5]- it "can count upward by 2" $ do- [5, 7 .. 11 :: Positive] `shouldBe` [5, 7, 9, 11]- [1, 3 .. 7 :: Positive] `shouldBe` [1, 3, 5, 7]- it "can count upward without exactly reaching its upper bound" $- [5, 7 .. 12 :: Positive] `shouldBe` [5, 7, 9, 11]- it "can count downward by 2" $- [11, 9 .. 5 :: Positive] `shouldBe` [11, 9, 7, 5]- it "can count downward by 2 without exactly reaching its lower bound" $- [11, 9 .. 4 :: Positive] `shouldBe` [11, 9, 7, 5]- it "can count downward with a lower bound of 1" $ do- [7, 5 .. 1 :: Positive] `shouldBe` [7, 5, 3, 1]- [8, 6 .. 1 :: Positive] `shouldBe` [8, 6, 4, 2]- it "can repeat 1 item indefinitely" $ do- take 5 [4, 4 .. 9 :: Positive] `shouldBe` [4, 4, 4, 4, 4]- take 5 [4, 4 .. 4 :: Positive] `shouldBe` [4, 4, 4, 4, 4]- it "can return 1 item" $ do- [4, 5 .. 4 :: Positive] `shouldBe` [4]- [4, 3 .. 4 :: Positive] `shouldBe` [4]- it "can return an empty list" $ do- [4, 4 .. 3 :: Positive] `shouldBe` []- [4, 5 .. 3 :: Positive] `shouldBe` []- [5, 4 .. 6 :: Positive] `shouldBe` []+ context "[a, b ..]" do+ it "can count upward by 1" do+ take 5 [5, 6 ..] ~> [5, 6, 7, 8, 9]+ take 5 [1, 2 ..] ~> [1, 2, 3, 4, 5]+ it "can count downward by 1" do+ [5, 4 ..] ~> [5, 4, 3, 2, 1]+ it "can count upward by 2" do+ take 5 [5, 7 ..] ~> [5, 7, 9, 11, 13]+ take 5 [1, 3 ..] ~> [1, 3, 5, 7, 9]+ it "can count downward by 2" do+ [9, 7 ..] ~> [9, 7, 5, 3, 1]+ it "can count downward by 2 without exactly reaching its lower bound" do+ [8, 6 ..] ~> [8, 6, 4, 2]+ it "can repeat 1 item indefinitely" do+ take 5 [4, 4 ..] ~> [4, 4, 4, 4, 4] - describe "deepseq @Signed" $ do- it "can succeed" $ do+ context "[a, b .. c]" do+ it "can count upward by 1" do+ [5, 6 .. 9] ~> [5, 6, 7, 8, 9]+ [1, 2 .. 5] ~> [1, 2, 3, 4, 5]+ it "can count downward by 1" do+ [9, 8 .. 5] ~> [9, 8, 7, 6, 5]+ it "can count upward by 2" do+ [5, 7 .. 11] ~> [5, 7, 9, 11]+ [1, 3 .. 7] ~> [1, 3, 5, 7]+ it "can count upward without exactly reaching its upper bound" do+ [5, 7 .. 12] ~> [5, 7, 9, 11]+ it "can count downward by 2" do+ [11, 9 .. 5] ~> [11, 9, 7, 5]+ it "can count downward by 2 without exactly reaching its lower bound" do+ [11, 9 .. 4] ~> [11, 9, 7, 5]+ it "can count downward with a lower bound of 1" do+ [7, 5 .. 1] ~> [7, 5, 3, 1]+ [8, 6 .. 1] ~> [8, 6, 4, 2]+ it "can repeat 1 item indefinitely" do+ take 5 [4, 4 .. 9] ~> [4, 4, 4, 4, 4]+ take 5 [4, 4 .. 4] ~> [4, 4, 4, 4, 4]+ it "can return 1 item" do+ [4, 5 .. 4] ~> [4]+ [4, 3 .. 4] ~> [4]+ it "can return an empty list" do+ [4, 4 .. 3] ~> []+ [4, 5 .. 3] ~> []+ [5, 4 .. 6] ~> []++ context "deepseq @Signed" do+ let (~>) = shouldBe @(Either X Signed)++ it "can succeed" do x <- force (NonZero MinusSign 5)- x `shouldBe` Right (-5)- it "can force an error" $ do- x <- force (throw X :: Signed)- x `shouldBe` Left X- it "can force an error in sign" $ do+ x ~> Right (-5)+ it "can force an error" do+ x <- force (throw X)+ x ~> Left X+ it "can force an error in sign" do x <- force (NonZero (throw X) 5)- x `shouldBe` Left X- it "can force an error in magnitude" $ do+ x ~> Left X+ it "can force an error in magnitude" do x <- force (NonZero MinusSign (throw X))- x `shouldBe` Left X+ x ~> Left X - describe "length" $ do- it "Natural" $ Natural.length "abc" `shouldBe` 3- it "Positive" $ Positive.length ('a' :| "bc") `shouldBe` 3+ context "length" do+ it "Natural" do+ Natural.length "abc" `shouldBe` 3+ it "Positive" do+ Positive.length ('a' :| "bc") `shouldBe` 3 data X = X deriving stock (Eq, Show)