packages feed

gambler 0.1.0.0 → 0.2.0.0

raw patch · 10 files changed

+195/−29 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Fold.Effectful.Examples.Boring: all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
- Fold.Effectful.Examples.Boring: and :: Monad m => EffectfulFold m Bool Bool
- Fold.Effectful.Examples.Boring: any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
- Fold.Effectful.Examples.Boring: element :: Eq a => Monad m => a -> EffectfulFold m a Bool
- Fold.Effectful.Examples.Boring: elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)
- Fold.Effectful.Examples.Boring: find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)
- Fold.Effectful.Examples.Boring: first :: Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: index :: Monad m => Natural -> EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: last :: Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: length :: Monad m => EffectfulFold m a Natural
- Fold.Effectful.Examples.Boring: list :: Monad m => EffectfulFold m a [a]
- Fold.Effectful.Examples.Boring: lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)
- Fold.Effectful.Examples.Boring: magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: mean :: Fractional a => Monad m => EffectfulFold m a a
- Fold.Effectful.Examples.Boring: minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: monoid :: Monoid a => Monad m => EffectfulFold m a a
- Fold.Effectful.Examples.Boring: notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool
- Fold.Effectful.Examples.Boring: null :: Monad m => EffectfulFold m a Bool
- Fold.Effectful.Examples.Boring: or :: Monad m => EffectfulFold m Bool Bool
- Fold.Effectful.Examples.Boring: product :: Num a => Monad m => EffectfulFold m a a
- Fold.Effectful.Examples.Boring: reverseList :: Monad m => EffectfulFold m a [a]
- Fold.Effectful.Examples.Boring: semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)
- Fold.Effectful.Examples.Boring: standardDeviation :: Floating a => Monad m => EffectfulFold m a a
- Fold.Effectful.Examples.Boring: sum :: Num a => Monad m => EffectfulFold m a a
- Fold.Effectful.Examples.Boring: variance :: Fractional a => Monad m => EffectfulFold m a a
- Fold.Effectful.Examples.Interesting: effect :: Monad m => (a -> m b) -> EffectfulFold m a ()
- Fold.Effectful.Examples.Interesting: effectMonoid :: (Monoid w, Monad m) => (a -> m w) -> EffectfulFold m a w
- Fold.Nonempty.Examples.Boring: all :: (a -> Bool) -> NonemptyFold a Bool
- Fold.Nonempty.Examples.Boring: and :: NonemptyFold Bool Bool
- Fold.Nonempty.Examples.Boring: any :: (a -> Bool) -> NonemptyFold a Bool
- Fold.Nonempty.Examples.Boring: element :: Eq a => a -> NonemptyFold a Bool
- Fold.Nonempty.Examples.Boring: elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)
- Fold.Nonempty.Examples.Boring: find :: (a -> Bool) -> NonemptyFold a (Maybe a)
- Fold.Nonempty.Examples.Boring: findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)
- Fold.Nonempty.Examples.Boring: first :: NonemptyFold a a
- Fold.Nonempty.Examples.Boring: index :: Natural -> NonemptyFold a (Maybe a)
- Fold.Nonempty.Examples.Boring: length :: NonemptyFold a Natural
- Fold.Nonempty.Examples.Boring: list :: NonemptyFold a [a]
- Fold.Nonempty.Examples.Boring: lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)
- Fold.Nonempty.Examples.Boring: mean :: Fractional a => NonemptyFold a a
- Fold.Nonempty.Examples.Boring: monoid :: Monoid a => NonemptyFold a a
- Fold.Nonempty.Examples.Boring: notElement :: Eq a => a -> NonemptyFold a Bool
- Fold.Nonempty.Examples.Boring: or :: NonemptyFold Bool Bool
- Fold.Nonempty.Examples.Boring: product :: Num a => NonemptyFold a a
- Fold.Nonempty.Examples.Boring: reverseList :: NonemptyFold a [a]
- Fold.Nonempty.Examples.Boring: standardDeviation :: Floating a => NonemptyFold a a
- Fold.Nonempty.Examples.Boring: sum :: Num a => NonemptyFold a a
- Fold.Nonempty.Examples.Boring: variance :: Fractional a => NonemptyFold a a
- Fold.Nonempty.Examples.Interesting: last :: NonemptyFold a a
- Fold.Nonempty.Examples.Interesting: list :: NonemptyFold a (NonEmpty a)
- Fold.Nonempty.Examples.Interesting: magma :: (a -> a -> a) -> NonemptyFold a a
- Fold.Nonempty.Examples.Interesting: maximum :: Ord a => NonemptyFold a a
- Fold.Nonempty.Examples.Interesting: maximumBy :: (a -> a -> Ordering) -> NonemptyFold a a
- Fold.Nonempty.Examples.Interesting: minimum :: Ord a => NonemptyFold a a
- Fold.Nonempty.Examples.Interesting: minimumBy :: (a -> a -> Ordering) -> NonemptyFold a a
- Fold.Nonempty.Examples.Interesting: reverseList :: NonemptyFold a (NonEmpty a)
- Fold.Nonempty.Examples.Interesting: semigroup :: Semigroup a => NonemptyFold a a
- Fold.Pure.Examples.Boring: all :: (a -> Bool) -> Fold a Bool
- Fold.Pure.Examples.Boring: and :: Fold Bool Bool
- Fold.Pure.Examples.Boring: any :: (a -> Bool) -> Fold a Bool
- Fold.Pure.Examples.Boring: element :: Eq a => a -> Fold a Bool
- Fold.Pure.Examples.Boring: elementIndex :: Eq a => a -> Fold a (Maybe Natural)
- Fold.Pure.Examples.Boring: find :: (a -> Bool) -> Fold a (Maybe a)
- Fold.Pure.Examples.Boring: findIndex :: (a -> Bool) -> Fold a (Maybe Natural)
- Fold.Pure.Examples.Boring: first :: Fold a (Maybe a)
- Fold.Pure.Examples.Boring: index :: Natural -> Fold a (Maybe a)
- Fold.Pure.Examples.Boring: last :: Fold a (Maybe a)
- Fold.Pure.Examples.Boring: lookup :: Eq a => a -> Fold (a, b) (Maybe b)
- Fold.Pure.Examples.Boring: magma :: (a -> a -> a) -> Fold a (Maybe a)
- Fold.Pure.Examples.Boring: maximum :: Ord a => Fold a (Maybe a)
- Fold.Pure.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
- Fold.Pure.Examples.Boring: minimum :: Ord a => Fold a (Maybe a)
- Fold.Pure.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
- Fold.Pure.Examples.Boring: notElement :: Eq a => a -> Fold a Bool
- Fold.Pure.Examples.Boring: null :: Fold a Bool
- Fold.Pure.Examples.Boring: or :: Fold Bool Bool
- Fold.Pure.Examples.Boring: semigroup :: Semigroup a => Fold a (Maybe a)
- Fold.Pure.Examples.Interesting: length :: Fold a Natural
- Fold.Pure.Examples.Interesting: list :: Fold a [a]
- Fold.Pure.Examples.Interesting: mean :: Fractional a => Fold a a
- Fold.Pure.Examples.Interesting: monoid :: Monoid a => Fold a a
- Fold.Pure.Examples.Interesting: product :: Num a => Fold a a
- Fold.Pure.Examples.Interesting: reverseList :: Fold a [a]
- Fold.Pure.Examples.Interesting: standardDeviation :: Floating a => Fold a a
- Fold.Pure.Examples.Interesting: sum :: Num a => Fold a a
- Fold.Pure.Examples.Interesting: variance :: Fractional a => Fold a a
- Fold.Shortcut.Examples.Boring: first :: ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: last :: ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: length :: ShortcutFold a Natural
- Fold.Shortcut.Examples.Boring: list :: ShortcutFold a [a]
- Fold.Shortcut.Examples.Boring: magma :: (a -> a -> a) -> ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: maximum :: Ord a => ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: mean :: Fractional a => ShortcutFold a a
- Fold.Shortcut.Examples.Boring: minimum :: Ord a => ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: monoid :: Monoid a => ShortcutFold a a
- Fold.Shortcut.Examples.Boring: product :: Num a => ShortcutFold a a
- Fold.Shortcut.Examples.Boring: reverseList :: ShortcutFold a [a]
- Fold.Shortcut.Examples.Boring: semigroup :: Semigroup a => ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Boring: standardDeviation :: Floating a => ShortcutFold a a
- Fold.Shortcut.Examples.Boring: sum :: Num a => ShortcutFold a a
- Fold.Shortcut.Examples.Boring: variance :: Fractional a => ShortcutFold a a
- Fold.Shortcut.Examples.Interesting: all :: (a -> Bool) -> ShortcutFold a Bool
- Fold.Shortcut.Examples.Interesting: and :: ShortcutFold Bool Bool
- Fold.Shortcut.Examples.Interesting: any :: (a -> Bool) -> ShortcutFold a Bool
- Fold.Shortcut.Examples.Interesting: element :: Eq a => a -> ShortcutFold a Bool
- Fold.Shortcut.Examples.Interesting: elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)
- Fold.Shortcut.Examples.Interesting: find :: (a -> Bool) -> ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Interesting: findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)
- Fold.Shortcut.Examples.Interesting: index :: Natural -> ShortcutFold a (Maybe a)
- Fold.Shortcut.Examples.Interesting: lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)
- Fold.Shortcut.Examples.Interesting: notElement :: Eq a => a -> ShortcutFold a Bool
- Fold.Shortcut.Examples.Interesting: null :: ShortcutFold a Bool
- Fold.Shortcut.Examples.Interesting: or :: ShortcutFold Bool Bool
- Fold.ShortcutNonempty.Examples.Boring: all :: (a -> Bool) -> ShortcutNonemptyFold a Bool
- Fold.ShortcutNonempty.Examples.Boring: and :: ShortcutNonemptyFold Bool Bool
- Fold.ShortcutNonempty.Examples.Boring: any :: (a -> Bool) -> ShortcutNonemptyFold a Bool
- Fold.ShortcutNonempty.Examples.Boring: element :: Eq a => a -> ShortcutNonemptyFold a Bool
- Fold.ShortcutNonempty.Examples.Boring: elementIndex :: Eq a => a -> ShortcutNonemptyFold a (Maybe Natural)
- Fold.ShortcutNonempty.Examples.Boring: find :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe a)
- Fold.ShortcutNonempty.Examples.Boring: findIndex :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe Natural)
- Fold.ShortcutNonempty.Examples.Boring: index :: Natural -> ShortcutNonemptyFold a (Maybe a)
- Fold.ShortcutNonempty.Examples.Boring: last :: ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: length :: ShortcutNonemptyFold a Natural
- Fold.ShortcutNonempty.Examples.Boring: list :: ShortcutNonemptyFold a [a]
- Fold.ShortcutNonempty.Examples.Boring: lookup :: Eq a => a -> ShortcutNonemptyFold (a, b) (Maybe b)
- Fold.ShortcutNonempty.Examples.Boring: magma :: (a -> a -> a) -> ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: maximum :: Ord a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: maximumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: mean :: Fractional a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: minimum :: Ord a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: minimumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: monoid :: Monoid a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: notElement :: Eq a => a -> ShortcutNonemptyFold a Bool
- Fold.ShortcutNonempty.Examples.Boring: or :: ShortcutNonemptyFold Bool Bool
- Fold.ShortcutNonempty.Examples.Boring: product :: Num a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: reverseList :: ShortcutNonemptyFold a [a]
- Fold.ShortcutNonempty.Examples.Boring: semigroup :: Semigroup a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: standardDeviation :: Floating a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: sum :: Num a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Boring: variance :: Fractional a => ShortcutNonemptyFold a a
- Fold.ShortcutNonempty.Examples.Interesting: first :: ShortcutNonemptyFold a a

Files

changelog.md view
@@ -1,3 +1,16 @@+## 0.2.0.0 (2023-02-22)++The "Examples" modules are no longer divided into "Interesting" and "Boring"+modules in the public API, because this leads to too many breaking releases.++`NonemptyFold` and `ShortcutNonemptyFold` now have their own `sum` and `product`+definitions instead of being lifted variants of the `Fold` and `ShortcutFold`+definitions. This makes it possible to use them with numeric types that do not+include additive or multiplicative identity values. For example, we now have a+test case which takes the sum over a non-empty list of positive integers. Since+a "positive integer" type does not include zero, previously this would result in+arithmetic underflow.+ ## 0.1.0.0 (2023-02-20)  Adds `ShortcutFold` and `ShortcutNonemptyFold`.
gambler.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0  name: gambler-version: 0.1.0.0+version: 0.2.0.0  category: Streaming synopsis: Composable, streaming, and efficient left folds@@ -40,8 +40,6 @@         Fold.Pure         Fold.Pure.Conversion         Fold.Pure.Examples-        Fold.Pure.Examples.Interesting-        Fold.Pure.Examples.Boring         Fold.Pure.Run         Fold.Pure.Type         Fold.Pure.Utilities@@ -49,8 +47,6 @@         Fold.Effectful         Fold.Effectful.Conversion         Fold.Effectful.Examples-        Fold.Effectful.Examples.Interesting-        Fold.Effectful.Examples.Boring         Fold.Effectful.Run         Fold.Effectful.Type         Fold.Effectful.Utilities@@ -58,8 +54,6 @@         Fold.Nonempty         Fold.Nonempty.Conversion         Fold.Nonempty.Examples-        Fold.Nonempty.Examples.Interesting-        Fold.Nonempty.Examples.Boring         Fold.Nonempty.Run         Fold.Nonempty.Type         Fold.Nonempty.Utilities@@ -68,8 +62,6 @@         Fold.Shortcut.Run         Fold.Shortcut.Type         Fold.Shortcut.Examples-        Fold.Shortcut.Examples.Interesting-        Fold.Shortcut.Examples.Boring         Fold.Shortcut.Conversion         Fold.Shortcut.Utilities @@ -77,14 +69,27 @@         Fold.ShortcutNonempty.Run         Fold.ShortcutNonempty.Type         Fold.ShortcutNonempty.Examples-        Fold.ShortcutNonempty.Examples.Interesting-        Fold.ShortcutNonempty.Examples.Boring         Fold.ShortcutNonempty.Conversion         Fold.ShortcutNonempty.Utilities      other-modules:         Strict +        Fold.Pure.Examples.Interesting+        Fold.Pure.Examples.Boring++        Fold.Effectful.Examples.Interesting+        Fold.Effectful.Examples.Boring++        Fold.Nonempty.Examples.Interesting+        Fold.Nonempty.Examples.Boring++        Fold.Shortcut.Examples.Interesting+        Fold.Shortcut.Examples.Boring++        Fold.ShortcutNonempty.Examples.Interesting+        Fold.ShortcutNonempty.Examples.Boring+ test-suite test-gambler     import: base     hs-source-dirs: test@@ -96,6 +101,7 @@         Spec.Effectful         Spec.Shortcut         Spec.ShortcutNonempty+        Positive     ghc-options:         -threaded     default-extensions:
source/Fold.hs view
@@ -27,7 +27,7 @@ import Fold.ShortcutNonempty.Type  import Fold.Effectful.Examples.Interesting-import Fold.Nonempty.Examples.Interesting hiding (list, reverseList)+import Fold.Nonempty.Examples.Interesting hiding (list, reverseList, sum, product) import Fold.Pure.Examples.Interesting import Fold.Shortcut.Examples.Interesting import Fold.ShortcutNonempty.Examples.Interesting
source/Fold/Nonempty/Examples/Boring.hs view
@@ -5,7 +5,7 @@     {- * Monoid -} monoid,     {- * Length -} length,     {- * Boolean -} and, or, all, any,-    {- * Numeric -} sum, product, mean, variance, standardDeviation,+    {- * Numeric -} mean, variance, standardDeviation,     {- * Search -} element, notElement, find, lookup,     {- * Index -} index, findIndex, elementIndex,     {- * List -} list, reverseList,@@ -18,7 +18,7 @@ import Data.Monoid (Monoid) import Fold.Nonempty.Type (NonemptyFold) import Numeric.Natural (Natural)-import Prelude (Floating, Fractional, Num)+import Prelude (Floating, Fractional)  import qualified Fold.Nonempty.Conversion as Convert import qualified Fold.Pure.Examples.Interesting as Pure@@ -52,14 +52,6 @@ {-| 'True' if any input satisfies the predicate -} any :: (a -> Bool) -> NonemptyFold a Bool any predicate = Convert.shortcutFold (Shortcut.any predicate)--{-| Adds the inputs -}-sum :: Num a => NonemptyFold a a-sum = Convert.fold Pure.sum--{-| Multiplies the inputs -}-product :: Num a => NonemptyFold a a-product = Convert.fold Pure.product  {-| Numerically stable arithmetic mean of the inputs -} mean :: Fractional a => NonemptyFold a a
source/Fold/Nonempty/Examples/Interesting.hs view
@@ -3,6 +3,7 @@     {- * General -} magma, semigroup,     {- * Endpoints -} last,     {- * Extrema -} maximum, minimum, maximumBy, minimumBy,+    {- * Numeric -} sum, product,     {- * List -} list, reverseList,   )   where@@ -13,6 +14,7 @@ import Data.List.NonEmpty (NonEmpty ((:|))) import Data.Ord (Ord, Ordering (GT), max, min) import Data.Semigroup (Semigroup, (<>))+import Prelude (Num, (+), (*))  import qualified Strict @@ -44,6 +46,14 @@ {-| The least input with respect to the given comparison function -} minimumBy :: (a -> a -> Ordering) -> NonemptyFold a a minimumBy cmp = magma (\x y -> case cmp x y of { GT -> y; _ -> x })++{-| Adds the inputs -}+sum :: Num a => NonemptyFold a a+sum = magma (+)++{-| Multiplies the inputs -}+product :: Num a => NonemptyFold a a+product = magma (*)  {-| All the inputs -} list :: NonemptyFold a (NonEmpty a)
source/Fold/ShortcutNonempty/Examples/Boring.hs view
@@ -55,11 +55,11 @@  {-| Adds the inputs (ambivalent) -} sum :: Num a => ShortcutNonemptyFold a a-sum = Convert.fold Pure.sum+sum = Convert.nonemptyFold Nonempty.sum  {-| Multiplies the inputs (ambivalent) -} product :: Num a => ShortcutNonemptyFold a a-product = Convert.fold Pure.product+product = Convert.nonemptyFold Nonempty.product  {-| Numerically stable arithmetic mean of the inputs (ambivalent) -} mean :: Fractional a => ShortcutNonemptyFold a a
source/Fold/ShortcutNonempty/Examples/Interesting.hs view
@@ -1,4 +1,8 @@-module Fold.ShortcutNonempty.Examples.Interesting where+module Fold.ShortcutNonempty.Examples.Interesting+  (+    {- * First/last -} first,+  )+  where  import Fold.ShortcutNonempty.Type 
+ test/Positive.hs view
@@ -0,0 +1,127 @@+module Positive (Positive) where++import Prelude (($), Enum, Eq, Ord, Show, (.), id)++import Numeric.Natural (Natural)+import Prelude (Int, Integer, Integral, Num, Real)++import qualified Control.Exception as Exception+import qualified Data.Bits as Bits+import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified Data.Ord as Ord+import qualified Prelude as Enum (Enum (..))+import qualified Prelude as Num (Integral (..), Num (..), Real (..), fromIntegral)+import qualified Text.Show as Show++newtype Positive = FromNatural{ toNatural :: Natural } deriving (Eq, Ord)++fromNatural :: Natural -> Positive+fromNatural = FromNatural++fromNaturalChecked :: Natural -> Positive+fromNaturalChecked x = case x of 0 -> Exception.throw Exception.Underflow; _ -> fromNatural x++toInteger :: Positive -> Integer+toInteger = Num.toInteger . toNatural++fromInteger :: Integer -> Positive+fromInteger = fromNatural . Num.fromInteger++fromIntegerChecked :: Integer -> Positive+fromIntegerChecked x = if x Ord.>= 1 then fromInteger x else Exception.throw Exception.Underflow++add :: Positive -> Positive -> Positive+add a b = fromNatural (toNatural a Num.+ toNatural b)++subtract :: Positive -> Positive -> Positive+subtract a b = fromNatural (toNatural a Num.- toNatural b)++subtractChecked :: Positive -> Positive -> Positive+subtractChecked a b = if a Ord.> b then subtract a b else Exception.throw Exception.Underflow++multiply :: Positive -> Positive -> Positive+multiply a b = fromNatural (toNatural a Num.* toNatural b)++addOne :: Positive -> Positive+addOne = fromNatural . (Num.+ 1) . toNatural++subtractOne :: Positive -> Positive+subtractOne = fromNatural . (Num.- 1) . toNatural++subtractOneChecked :: Positive -> Positive+subtractOneChecked x = case x of { 1 -> Exception.throw Exception.Underflow; _ -> subtractOne x }++toIntChecked :: Positive -> Int+toIntChecked = Maybe.fromMaybe (Exception.throw Exception.Overflow) . Bits.toIntegralSized . toNatural++fromInt :: Int -> Positive+fromInt = fromNatural . Num.fromIntegral++fromIntChecked :: Int -> Positive+fromIntChecked x = case Num.signum x of { 1 -> fromInt x; _ -> Exception.throw Exception.Underflow }++enumFrom :: Positive -> [Positive]+enumFrom = List.map fromNatural . Enum.enumFrom . toNatural++enumFromTo :: Positive -> Positive -> [Positive]+enumFromTo a b = List.map fromNatural $ Enum.enumFromTo (toNatural a) (toNatural b)++enumFromThen :: Positive -> Positive -> [Positive]+enumFromThen a b = if a Ord.< b then ascending else descending+  where+    ascending = List.map fromNatural $ Enum.enumFromThen (toNatural a) (toNatural b)+    descending = List.map fromInteger $ List.takeWhile (Ord.>= 1) $+        Enum.enumFromThen (toInteger a) (toInteger b)++enumFromThenTo :: Positive -> Positive -> Positive -> [Positive]+enumFromThenTo a b c = if a Ord.< b then ascending else descending+  where+    ascending = List.map fromNatural $ Enum.enumFromThenTo (toNatural a) (toNatural b) (toNatural c)+    descending = List.map fromInteger $ List.takeWhile (Ord.>= 1) $+        Enum.enumFromThenTo (toInteger a) (toInteger b) (toInteger c)++type Div a = a -> a -> (a, a)++divisionOp :: Div Natural -> Div Positive+divisionOp o a b =+    let (q, r) = o (toNatural a) (toNatural b)+    in (fromNaturalChecked q, fromNaturalChecked r)++instance Num Positive+  where+    abs = id+    negate = \_ -> Exception.throw Exception.Underflow+    signum = \_ -> fromNatural 1+    fromInteger = fromIntegerChecked+    (+) = add+    (*) = multiply+    (-) = subtractChecked++instance Enum Positive+  where+    succ = addOne+    pred = subtractOneChecked++    fromEnum = toIntChecked+    toEnum = fromIntChecked++    enumFrom = enumFrom+    enumFromTo = enumFromTo+    enumFromThen = enumFromThen+    enumFromThenTo = enumFromThenTo++instance Real Positive+  where+    toRational = Num.toRational . toInteger++instance Integral Positive+  where+    toInteger = toInteger+    quotRem = divisionOp Num.quotRem+    divMod = divisionOp Num.divMod++instance Show Positive+  where+    show = Show.show . toNatural+    showsPrec i = Show.showsPrec i . toNatural
test/Spec/Nonempty.hs view
@@ -5,6 +5,7 @@ import Test.Hspec  import Data.List.NonEmpty (NonEmpty ((:|)))+import Positive (Positive) import Prelude (String, Integer)  spec :: SpecWith ()@@ -34,3 +35,9 @@         describe "reverseList" do             it "gets all inputs in reverse" do                 run reverseList xs `shouldBe` [4, 3, 2, 1]++    describe "sum/product" do+        it "sum works with Positive" do+            run sum [1,2,5] `shouldBe` (8 :: Positive)+        it "product works with Positive" do+            run product [1,2,5] `shouldBe` (10 :: Positive)
test/Spec/ShortcutNonempty.hs view
@@ -4,12 +4,13 @@  import Test.Hspec -import Control.Applicative (pure, (<$>), (<*>))-import Prelude (Integer, undefined)-import Data.List.NonEmpty (NonEmpty ((:|)))-import Data.Maybe (Maybe (Just))+import Control.Applicative (pure, (<$>), (<*>), liftA2) import Data.Bool (Bool (..)) import Data.List ((++))+import Data.List.NonEmpty (NonEmpty ((:|)))+import Data.Maybe (Maybe (Just))+import Positive (Positive)+import Prelude (Integer, undefined)  import qualified Data.Char as Char @@ -57,3 +58,9 @@             run or [True,False] `shouldBe` True         it "is lazy" do             run or (True :| undefined) `shouldBe` True++    describe "sum/product" do+        it "sum works with Positive" do+            run (liftA2 (,) (index 2) sum) [1,2,5,7] `shouldBe` (Just 5, 8 :: Positive)+        it "product works with Positive" do+            run (liftA2 (,) (index 2) product) [1,2,5,3] `shouldBe` (Just 5, 10 :: Positive)