packages feed

mappings 0.2.2.0 → 0.3.0.0

raw patch · 4 files changed

+103/−16 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Mapping.Piecewise: atLeast :: k -> Piecewise k Bool
- Data.Mapping.Piecewise: piecewiseFromAsc :: Eq k => v -> [(k, v)] -> Piecewise k v
+ Data.Mapping.Piecewise: fromAscListUnsafe :: v -> [(k, v)] -> Piecewise k v
+ Data.Mapping.Piecewise: gluePiecewise :: Eq v => Piecewise k v -> k -> Piecewise k v -> Piecewise k v
+ Data.Mapping.Piecewise: greaterThan :: Enum k => k -> Piecewise k Bool
+ Data.Mapping.Piecewise: greaterThanOrEqual :: k -> Piecewise k Bool
+ Data.Mapping.Piecewise: instance GHC.Classes.Eq k => GHC.Base.Functor (Data.Mapping.Piecewise.Piecewise k)
+ Data.Mapping.Piecewise: lessThanOrEqual :: Enum k => k -> Piecewise k Bool
+ Data.Mapping.Piecewise: mapKeysAntitonic :: (k -> l) -> Piecewise k v -> Piecewise l v
+ Data.Mapping.Piecewise: mapKeysMonotonic :: (k -> l) -> Piecewise k v -> Piecewise l v
+ Data.Mapping.Piecewise: mjoin :: (Ord k, Eq w) => (v -> Piecewise k w) -> Piecewise k v -> Piecewise k w
+ Data.Mapping.Piecewise: rightEnd :: Piecewise k v -> v
+ Data.Mapping.Piecewise: splitPiecewise :: Ord k => k -> Piecewise k v -> (Piecewise k v, Piecewise k v)
- Data.Mapping.Piecewise: fromAscList :: (Ord k, Eq v) => v -> [(k, v)] -> Piecewise k v
+ Data.Mapping.Piecewise: fromAscList :: Eq v => v -> [(k, v)] -> Piecewise k v

Files

CHANGELOG.md view
@@ -1,3 +1,11 @@+## [0.3.0.0] - 2023-12-06++* Extra functionality for `Data.Mapping.Piecewise`++## [0.2.2.0] - 2023-11-22++* Uses a newer version of `cond` allowing many newtypes to be derived.+ ## [0.1.0.0] - 2023-11-09  * `baseLength` and `decisionLength` functions
mappings.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           mappings-version:        0.2.2.0+version:        0.3.0.0 synopsis:       Types which represent functions k -> v description:    A typeclass and a number of implementations; please read README.md on github category:       Data structures@@ -19,6 +19,8 @@ extra-doc-files:     README.md     CHANGELOG.md++tested-with:    GHC==9.6.2, GHC==9.4.5, GHC==9.2.8  source-repository head   type: git
src/Data/Mapping/Piecewise.hs view
@@ -11,6 +11,7 @@ #endif import Control.Applicative (liftA3) import Data.Algebra.Boolean+import qualified Data.Map.Internal as MI import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import qualified Data.Set as S@@ -24,41 +25,72 @@ -- right-continuous: values are in general defined on intervals $a -- \leq x < b$ which are closed on the left and open on the right. data Piecewise k v = Piecewise {+  -- | The value taken for sufficiently small keys   leftEnd :: v,   starts :: Map k v } deriving (Eq, Ord) -piecewiseFromAsc :: Eq k => v -> [(k,v)] -> Piecewise k v-piecewiseFromAsc k = Piecewise k . M.fromAscList+-- | The value taken for sufficiently large keys+rightEnd :: Piecewise k v -> v+rightEnd (Piecewise a m) = case M.lookupMax m of+  Nothing    -> a+  Just (_,b) -> b +-- | Assumes the keys are distinct and increasing (but consecutive+-- values may be the same, in which case the intervening keys are+-- removed)+fromAscList :: (Eq v) => v -> [(k,v)] -> Piecewise k v+fromAscList = let+  inner _ [] = []+  inner a ((y,b):r)+    | a == b    = inner a r+    | otherwise = (y,b):inner b r+  run x = Piecewise x . M.fromDistinctAscList . inner x+  in run+ instance (Show k, Show v) => Show (Piecewise k v) where   showsPrec d (Piecewise k m) =-    ("piecewiseFromAsc " <>) .+    ("fromAscList " <>) .     showsPrec d k .     (" " <>) .     showList (M.toList m) +-- | Assumes that the keys are distinct and increasing, and also that+-- consecutive values are distinct+fromAscListUnsafe :: v -> [(k,v)] -> Piecewise k v+fromAscListUnsafe k = Piecewise k . M.fromDistinctAscList++-- | Takes value `a` for keys less than `x` and `b` otherwise changeAt :: v -> k -> v -> Piecewise k v changeAt a x b = Piecewise a $ M.singleton x b -atLeast :: k -> Piecewise k Bool-atLeast k = changeAt False k True+-- | Is the value greater than or equal to `k`?+greaterThanOrEqual :: k -> Piecewise k Bool+greaterThanOrEqual k = changeAt False k True +-- | Is the value less than `k`? lessThan :: k -> Piecewise k Bool lessThan k = changeAt True k False -fromAscList :: (Ord k, Eq v) => v -> [(k,v)] -> Piecewise k v-fromAscList = let-  inner _ [] = []-  inner a ((y,b):r)-    | a == b    = inner a r-    | otherwise = (y,b):inner b r-  run x = Piecewise x . M.fromAscList . inner x-  in run+-- | Is the value greater than `k`? This is subject to the usual+-- concerns about `Enum` (it not to be used with floating-point+-- arithmetic, for example)+greaterThan :: Enum k => k -> Piecewise k Bool+greaterThan = greaterThanOrEqual . succ +-- | Is the value less than or equal to `k`? This is subject to the+-- usual concerns about `Enum` (it not to be used with floating-point+-- arithmetic, for example)+lessThanOrEqual :: Enum k => k -> Piecewise k Bool+lessThanOrEqual = lessThan . succ++-- | All values, in order of increasing key values :: Piecewise k v -> [v] values (Piecewise x m) = x : M.elems m +instance (Eq k) => Functor (Piecewise k) where+  fmap p (Piecewise a f) = fromAscListUnsafe (p a) (fmap p <$> M.toList f)+ instance Foldable (Piecewise k) where   foldMap f (Piecewise a m) = f a <> foldMap f m @@ -72,7 +104,7 @@    isConst (Piecewise a f) = if M.null f then Just a else Nothing -  mmap p (Piecewise a f) = fromAscList (p a) (fmap p <$> M.toList f)+  mmap = fmap    mtraverse p (Piecewise a f) = liftA2 fromAscList (p a) (traverse (traverse p) $ M.toList f) @@ -150,3 +182,48 @@  deriving via (AlgebraWrapper k (Piecewise k) b)   instance (Ord k, Ord b, Boolean b) => Boolean (Piecewise k b)++-- | Alter keys according to a function, assumed to be monotone (not checked)+mapKeysMonotonic :: (k -> l) -> Piecewise k v -> Piecewise l v+mapKeysMonotonic f (Piecewise a m) = Piecewise a (M.mapKeysMonotonic f m)++-- | Alter keys according to a function, assumed to be antitone (not checked)+mapKeysAntitonic :: (k -> l) -> Piecewise k v -> Piecewise l v+mapKeysAntitonic f = let++  inner a MI.Tip = (a, MI.Tip)+  inner a (MI.Bin s x b l r) = let+    (a', l') = inner a l+    (b', r') = inner b r+    in (b', MI.Bin s (f x) a' r' l')++  start (Piecewise a m) = uncurry Piecewise $ inner a m+  in start++-- | Split in two: one which assumes keys are less than `k`, and one+-- which assumes them greater than or equal to `k`.+splitPiecewise :: Ord k => k -> Piecewise k v -> (Piecewise k v, Piecewise k v)+splitPiecewise k (Piecewise a m) = case M.splitLookup k m of+  (m1, Just b, m2) -> (Piecewise a m1, Piecewise b m2)+  (m1, Nothing, m2) -> let+    p1 = Piecewise a m1+    in (p1, Piecewise (rightEnd p1) m2)++-- | Assemble two maps; it is assumed that all keys in the left-hand+-- map are less than `k` and all keys in the right-hand map are+-- greater than or equal to `k` (which is not checked).+gluePiecewise :: (Eq v) => Piecewise k v -> k -> Piecewise k v -> Piecewise k v+gluePiecewise p@(Piecewise a m) k (Piecewise c n) = let+  b = rightEnd p+  in Piecewise a (if b == c then MI.link2 m n else MI.link k c m n)++-- | This is almost a monad (with `cst` as `pure`) except that we need+-- an `Eq` instance on the values.+mjoin :: (Ord k, Eq w) => (v -> Piecewise k w) -> Piecewise k v -> Piecewise k w+mjoin f (Piecewise a m) = let+  inner p []        = p+  inner p ((k,q):l) = let+    (p',  _) = splitPiecewise k p+    (_ , q') = splitPiecewise k q+    in gluePiecewise p' k $ inner q' l+  in inner (f a) (fmap f <$> M.toList m)
test/Data/Mapping/DecisionSpec.hs view
@@ -114,7 +114,7 @@     let xyz = M.fromList [("X", 1), ("Y", 1), ("Z", 1)]     let monomials = M.fromList [(xy2, 1::Int), (x2y, 2), (xyz, 3)]     let f i b = if b then i else 0-    let d = M.foldlWithKey' (\t m i -> merge max t (mmap (f i) . buildAll $ fmap atLeast m)) (cst 0) monomials+    let d = M.foldlWithKey' (\t m i -> merge max t (mmap (f i) . buildAll $ fmap greaterThanOrEqual m)) (cst 0) monomials     let mapAct m = act d (\a -> M.findWithDefault 0 a $ M.fromList m)      it "should get the right monomial for w^2y^4" $ do