plur 0.1.0.0 → 0.2.0.0
raw patch · 4 files changed
+87/−24 lines, 4 filesdep +hedgehogdep +hedgehog-classesdep +plurdep ~base
Dependencies added: hedgehog, hedgehog-classes, plur
Dependency ranges changed: base
Files
- ChangeLog.md +7/−1
- plur.cabal +26/−4
- src/Data/Plur.hs +23/−19
- test/Properties.hs +31/−0
ChangeLog.md view
@@ -1,5 +1,11 @@ # Revision history for plur -## 0.1.0.0 -- YYYY-mm-dd+## 0.2.0.0 -- 2019-02-12++Breaking changes: made all fields strict++Other stuff: Added documentation for `Plur` and `count`.++## 0.1.0.0 -- 2018-05-24 * First version. Released on an unsuspecting world.
plur.cabal view
@@ -1,21 +1,43 @@ name: plur-version: 0.1.0.0+version: 0.2.0.0 synopsis: Plurality monad: Zero, one, or at least two.--- description:+description:+ Often when counting you don't need an exact count, but only whether there are+ two things. Two examples:+ .+ When searching for inhabitants of a type (implementations of a program), you+ want to be able to tell whether there are (a) no possible inhabitants, (b) a+ unique inhabitant, or (c) multiple inhabitants.+ .+ When displaying the name of a variable, if there's exactly one variable of a+ given name ("a") you can just use that name, but if there are multiples you+ might use a unique id to disambiguate them ("a1" vs "a2"). license: BSD3 license-file: LICENSE author: Joel Burget maintainer: joelburget@gmail.com-copyright: (c) 2018 Joel Burget+copyright: (c) 2018-2019 Joel Burget category: Data build-type: Simple extra-source-files: ChangeLog.md cabal-version: >=1.10+tested-with: GHC == 8.6.3 library exposed-modules: Data.Plur build-depends:- base >=4.11 && <4.12,+ base >=4.3 && <4.14, semigroups >= 0.18 hs-source-dirs: src default-language: Haskell2010++test-suite Properties+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Properties.hs+ build-depends:+ base,+ plur,+ hedgehog,+ hedgehog-classes >= 0.1.1+ default-language: Haskell2010
src/Data/Plur.hs view
@@ -1,18 +1,20 @@-{-# language LambdaCase #-} module Data.Plur (Plur(..), count) where +import Control.Applicative+import Data.Foldable import Data.Monoid-import Data.Semigroup+import Data.Semigroup as Semigroup+import Data.Traversable --- Plurality monad: Zero, one, or at least two.+-- | Plurality monad: Zero, one, or at least two. data Plur a = Zero- | One a- | Two a a+ | One !a+ | Two !a !a deriving (Show, Eq, Ord) instance Functor Plur where- fmap f = \case+ fmap f plur = case plur of Zero -> Zero One a -> One (f a) Two a1 a2 -> Two (f a1) (f a2)@@ -20,25 +22,26 @@ instance Applicative Plur where pure = One - (<*>) Zero _ = Zero- (<*>) _ Zero = Zero- (<*>) (One f) x = fmap f x- (<*>) (Two f1 f2) x = fmap f1 x <> fmap f2 x+ Zero <*> _ = Zero+ _ <*> Zero = Zero+ One f <*> x = fmap f x+ Two f1 f2 <*> x = fmap f1 x `mappend` fmap f2 x instance Monad Plur where- (>>=) x f = case x of+ return = pure+ x >>= f = case x of Zero -> Zero One x1 -> f x1- Two x1 x2 -> f x1 <> f x2+ Two x1 x2 -> f x1 `mappend` f x2 instance Foldable Plur where- foldMap f = \case+ foldMap f plur = case plur of Zero -> mempty One a -> f a- Two a1 a2 -> f a1 <> f a2+ Two a1 a2 -> f a1 `mappend` f a2 instance Traversable Plur where- traverse f = \case+ traverse f plur = case plur of Zero -> pure Zero One a -> One <$> f a Two a1 a2 -> Two <$> f a1 <*> f a2@@ -48,14 +51,15 @@ Zero <> r2 = r2 One x <> One y = Two x y One x <> Two y _ = Two x y- Two x _ <> One y = Two x y- Two x _ <> Two y _ = Two x y+ Two x y <> _ = Two x y instance Monoid (Plur a) where- mempty = Zero+ mempty = Zero+ mappend = (Semigroup.<>) +-- | Erase occurrences, resulting in @0@, @1@, or @2@. count :: Plur a -> Int-count = \case+count plur = case plur of Zero -> 0 One _ -> 1 Two _ _ -> 2
+ test/Properties.hs view
@@ -0,0 +1,31 @@+module Main (main) where++import Control.Applicative+import Data.Plur+import System.Exit+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++import Hedgehog+import Hedgehog.Classes++genPlur :: Gen x -> Gen (Plur x)+genPlur gen = Gen.choice+ [ pure Zero+ , One <$> gen+ , Two <$> gen <*> gen+ ]++main :: IO ()+main = do+ result <- lawsCheckMany+ [ ("Plur",+ [ functorLaws genPlur+ , applicativeLaws genPlur+ , monadLaws genPlur+ , traversableLaws genPlur+ , semigroupLaws $ genPlur Gen.unicode+ , monoidLaws $ genPlur Gen.unicode+ ])+ ]+ exitWith $ if result then ExitSuccess else ExitFailure 1