packages feed

agreeing 0.2.0.0 → 0.2.1.0

raw patch · 4 files changed

+64/−11 lines, 4 files

Files

CHANGELOG.md view
@@ -6,6 +6,10 @@ and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/). +## 0.2.1.0 - 2023-10-30++* `Eq`, `Ord`, `Show`, `Applicative` and `Monad` instances+ ## 0.1.0.0 - 2023-03-15 -	Initial version+Initial version
README.md view
@@ -2,3 +2,15 @@  A simple data structure helping us ask questions of the following sort: "does all this data have the same /BLANK/ and if so what is it?"++For example:++        doTheseHaveTheSameLength :: [String] -> String+        doTheseHaveTheSameLength l = case foldMap (Somebody . length) of+          Somebody n -> "They all have length " <> show n+          Nobody     -> "The lengths differ"+          Anybody    -> "You didn't give me any strings"++This can of course be done with `Maybe (Maybe x)` instead, but doing+so runs the risk of getting confused: which is `Nothing` and which is+`Just Nothing`?
agreeing.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.36.0. -- -- see: https://github.com/sol/hpack  name:           agreeing-version:        0.2.0.0+version:        0.2.1.0 synopsis:       Idiomatic data structure for agreement description:    Please see the README on GitHub at <https://github.com/jcranch/agreeing#readme> category:       Data
src/Data/Agreement.hs view
@@ -9,6 +9,26 @@ -- >   Somebody n -> "They all have length " <> show n -- >   Nobody     -> "The lengths differ" -- >   Anybody    -> "You didn't give me any strings"+--+-- This can of course be done with `Maybe (Maybe x)` instead, but+-- doing so runs the risk of getting confused: which is `Nothing` and+-- which is `Just Nothing`?+--+-- Unfortunately, there are two `Applicative` instances.+--+-- One is easy to motivate intrinsically. If we think of `Anybody` as+-- an empty list, `Somebody` as a singleton list, and `Nobody` as a+-- multi-element list, and think of the applicative instance on as+-- corresponding to the cartesian product, then we get an+-- `Applicative` instance with+--+-- > Anybody <*> Anybody = Anybody+-- > Anybody <*> Nobody = Nobody+--+-- This however cannot possibly correspond to a `Monad` instance (if+-- the first argument of `>>=` is Anybody, there's no way of+-- inspecting the second). We thus choose another, which does.+ module Data.Agreement (   Agreement(..),   getSomebody,@@ -25,6 +45,7 @@ -- --   * `Anybody` is a failure to make any choice. data Agreement a = Anybody | Somebody a | Nobody+  deriving (Eq, Ord, Show)  -- | This picks out consistent choices as `Just`. getSomebody :: Agreement a -> Maybe a@@ -32,18 +53,34 @@ getSomebody _ = Nothing  instance Functor Agreement where-  fmap _ Anybody = Anybody+  fmap _ Anybody      = Anybody   fmap f (Somebody x) = Somebody (f x)-  fmap _ Nobody = Nobody+  fmap _ Nobody       = Nobody +-- | Not the only possible instance: see introduction+instance Applicative Agreement where+  pure = Somebody+  Nobody     <*> _ = Nobody+  Anybody    <*> _ = Anybody+  Somebody f <*> x = f <$> x+  liftA2 _ Nobody       _ = Nobody+  liftA2 _ Anybody      _ = Anybody+  liftA2 f (Somebody x) y = f x <$> y++instance Monad Agreement where+  return = pure+  Nobody     >>= _ = Nobody+  Anybody    >>= _ = Anybody+  Somebody x >>= f = f x+ instance (Eq a) => Semigroup (Agreement a) where-  Anybody <> x = x-  Nobody <> _ = Nobody-  Somebody x <> Anybody = Somebody x-  Somebody _ <> Nobody = Nobody+  Nobody     <> _          = Nobody+  Anybody    <> x          = x+  Somebody _ <> Nobody     = Nobody+  Somebody x <> Anybody    = Somebody x   Somebody x <> Somebody y-    | x == y = Somebody x-    | otherwise = Nobody+    | x == y               = Somebody x+    | otherwise            = Nobody   stimes = stimesIdempotentMonoid  instance (Eq a) => Monoid (Agreement a) where