packages feed

mini 1.6.5.0 → 1.7.0.0

raw patch · 7 files changed

+95/−117 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Mini.Hash.Murmur32: add :: Hashable a => a -> Hash32 -> Hash32
- Mini.Hash.Murmur32: data Hash32
- Mini.Hash.Murmur32: digest :: Hash32 -> Word32
- Mini.Hash.Murmur32: instance GHC.Classes.Eq Mini.Hash.Murmur32.Hash32
- Mini.Hash.Murmur32: instance GHC.Classes.Ord Mini.Hash.Murmur32.Hash32
- Mini.Hash.Murmur32: instance GHC.Show.Show Mini.Hash.Murmur32.Hash32
- Mini.Hash.Murmur32: seed :: Word32 -> Hash32
- Mini.Random.Class: instance Mini.Random.Class.Generator Mini.Hash.Murmur32.Hash32
- Mini.Transformers.EitherT: anticipate :: forall (m :: Type -> Type) e a. Monad m => EitherT e m a -> EitherT e m (Either e a)
- Mini.Transformers.MaybeT: anticipate :: forall (m :: Type -> Type) a. Monad m => MaybeT m a -> MaybeT m (Maybe a)
+ Mini.Hash.Class: class Hash h s d | h -> s d
+ Mini.Hash.Class: digest :: Hash h s d => h -> d
+ Mini.Hash.Class: hash :: (Hash h s d, Hashable a) => a -> s -> h
+ Mini.Hash.Murmur32: data Murmur32
+ Mini.Hash.Murmur32: instance GHC.Classes.Eq Mini.Hash.Murmur32.Murmur32
+ Mini.Hash.Murmur32: instance GHC.Classes.Ord Mini.Hash.Murmur32.Murmur32
+ Mini.Hash.Murmur32: instance GHC.Show.Show Mini.Hash.Murmur32.Murmur32
+ Mini.Hash.Murmur32: instance Mini.Hash.Class.Hash Mini.Hash.Murmur32.Murmur32 GHC.Word.Word32 GHC.Word.Word32
+ Mini.Transformers.EitherT: eitherT :: forall (m :: Type -> Type) e e' b a. Monad m => (e -> EitherT e' m b) -> (a -> EitherT e' m b) -> EitherT e m a -> EitherT e' m b
+ Mini.Transformers.MaybeT: maybeT :: forall (m :: Type -> Type) b a. Monad m => MaybeT m b -> (a -> MaybeT m b) -> MaybeT m a -> MaybeT m b

Files

CHANGELOG.md view
@@ -1,3 +1,10 @@+1.7.0.0 [2026-07-21]+--------------------+* Mini.Transformers.MaybeT: Replace 'anticipate' with 'maybeT'+* Mini.Transformers.EitherT: Replace 'anticipate' with 'eitherT'+* Hash.Class: Add class 'Hash'+  * Rework Murmur32 for the new Hash class+ 1.6.5.0 [2026-07-20] -------------------- * Mini.Transformers.MaybeT: Add 'just'
mini.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               mini-version:            1.6.5.0+version:            1.7.0.0 license:            MIT license-file:       LICENSE author:             Victor Wallsten <victor.wallsten@protonmail.com>
src/Mini/Hash/Class.hs view
@@ -1,6 +1,12 @@--- | The class of hashable types+{-# LANGUAGE FunctionalDependencies #-}++-- | Hash functions and hashable types module Mini.Hash.Class (-  -- * Class+  -- * Classes+  Hash (+    hash,+    digest+  ),   Hashable (     toBytes   ),@@ -42,7 +48,14 @@   (.),  ) --- Class+-- Classes++-- | The class of hash functions+class Hash h s d | h -> s d where+  -- | Make a hash value from a hashable value and a seed+  hash :: (Hashable a) => a -> s -> h+  -- | Extract the digest of a hash value+  digest :: h -> d  -- | Instances should use little-endian byte order class Hashable a where
src/Mini/Hash/Murmur32.hs view
@@ -1,14 +1,9 @@--- | An implementation of MurmurHash3_x86_32 supporting incremental addition+{-# LANGUAGE MultiParamTypeClasses #-}++-- | An implementation of MurmurHash3_x86_32 module Mini.Hash.Murmur32 (   -- * Type-  Hash32,--  -- * Construction-  seed,--  -- * Operations-  add,-  digest,+  Murmur32, ) where  import Data.Bits (@@ -16,9 +11,7 @@   shiftL,   shiftR,   xor,- )-import Data.Function (-  on,+  (.&.),  ) import Data.Word (   Word32,@@ -26,10 +19,11 @@  ) import Mini.Data.Recursion (   bool,-  uncurry3,  ) import Mini.Hash.Class (-  Hashable,+  Hash,+  digest,+  hash,   toBytes,  ) import Numeric (@@ -39,79 +33,69 @@   Eq,   Ord,   Show,-  compare,-  foldr,   fromIntegral,-  null,   showsPrec,   ($),   (*),   (+),   (.),-  (<>),-  (==),+  (/=),  )  -- Type  -- | Abstract representation of a 32-bit hash value-data Hash32 = Hash32 Word32 Word32 [Word8]--instance Eq Hash32 where-  (==) = (==) `on` digest--instance Ord Hash32 where-  compare = compare `on` digest+newtype Murmur32 = Murmur32 Word32+  deriving (Eq, Ord) -instance Show Hash32 where+instance Show Murmur32 where   showsPrec _ = showHex . digest --- Construction---- | Make a hash from a seed-seed :: Word32 -> Hash32-seed s = Hash32 s 0 []---- Operations---- | Add a hashable type to a hash-add :: (Hashable a) => a -> Hash32 -> Hash32-add a = addBytes $ toBytes a---- | Get the digest of a hash-digest :: Hash32 -> Word32-digest (Hash32 h1 len t) =-  let (k0, tlen) =-        foldr-          (\a (b, n) -> (fromIntegral a `xor` (b `shiftL` 8), n + 1))-          (0, 0)-          t-      len' = len + tlen-      k1 = k0 * 0xcc9e2d51-      k2 = k1 `rotateL` 15-      k3 = k2 * 0x1b873593-      h2 = h1 `xor` k3-   in mix-        . bool-          (h2 `xor` len')-          (h1 `xor` len)-        $ null t+instance Hash Murmur32 Word32 Word32 where+  hash a s =+    let bs = toBytes a+        (len, h, k) = body s bs+     in Murmur32 . final len $ tail len h k+  digest (Murmur32 d) = d  -- Helpers -addBytes :: [Word8] -> Hash32 -> Hash32-addBytes new (Hash32 h0 len0 old) = uncurry3 Hash32 $ go h0 len0 (old <> new)+body :: Word32 -> [Word8] -> (Word32, Word32, Word32)+body h0 bs = go 0 h0 bs  where-  go h len (a : b : c : d : rest) =+  go len h (a : b : c : d : rest) =     let d' = fromIntegral d `shiftL` 24         c' = fromIntegral c `shiftL` 16         b' = fromIntegral b `shiftL` 8         a' = fromIntegral a-        w = a' `xor` b' `xor` c' `xor` d'-        h' = murmur w h-        len' = len + 4-     in go h' len' rest-  go h len bs = (h, len, bs)+        k = a' `xor` b' `xor` c' `xor` d'+     in go (len + 4) (murmur k h) rest+  go len h (a : b : c : _) =+    let c' = fromIntegral c `shiftL` 16+        b' = fromIntegral b `shiftL` 8+        a' = fromIntegral a+        k = a' `xor` b' `xor` c'+     in (len + 3, h, k)+  go len h (a : b : _) =+    let b' = fromIntegral b `shiftL` 8+        a' = fromIntegral a+        k = a' `xor` b'+     in (len + 2, h, k)+  go len h (a : _) = (len + 1, h, fromIntegral a)+  go len h _ = (len, h, 0)++++tail :: Word32 -> Word32 -> Word32 -> Word32+tail len h0 k0 =+    let k1 = k0 * 0xcc9e2d51+        k2 = k1 `rotateL` 15+        k3 = k2 * 0x1b873593+        h1 = h0 `xor` k3+     in bool h0 h1 $ len .&. 3 /= 0++final :: Word32 -> Word32 -> Word32+final len h = mix $ h `xor` len  murmur :: Word32 -> Word32 -> Word32 murmur k1 h1 =
src/Mini/Random/Class.hs view
@@ -23,7 +23,6 @@   shiftL,   shiftR,   (.&.),-  (.|.),  ) import Data.Int (   Int16,@@ -41,11 +40,6 @@   Word64,   Word8,  )-import Mini.Hash.Murmur32 (-  Hash32,-  add,-  digest,- ) import Mini.Random.SplitMix (   SplitMix,  )@@ -78,15 +72,6 @@   nextWord32 :: g -> (Word32, g)   nextWord32 = first fromIntegral . nextWord64   nextWord64 :: g -> (Word64, g)--instance Generator Hash32 where-  nextWord32 h = let d = digest h in (d, add d h)-  nextWord64 h =-    let (lo, g) = nextWord32 h-        (hi, g') = nextWord32 g-        lo' = fromIntegral lo-        hi' = fromIntegral hi `shiftL` 32-     in (lo' .|. hi', g')  instance Generator SplitMix where   nextWord32 = SplitMix.nextWord32
src/Mini/Transformers/EitherT.hs view
@@ -7,7 +7,7 @@   runEitherT,    -- * Operations-  anticipate,+  eitherT,   left,   right, ) where@@ -47,7 +47,6 @@   pure,   ($),   (.),-  (<$>),   (<*>),   (>>=),  )@@ -69,20 +68,10 @@  instance (Monad m, Monoid e) => Alternative (EitherT e m) where   empty = left mempty-  m <|> n =-    EitherT $-      runEitherT m-        >>= either-          (\e -> either (Left . mappend e) Right <$> runEitherT n)-          (pure . Right)+  m <|> n = eitherT (\e -> eitherT (left . mappend e) right n) right m  instance (Monad m) => Monad (EitherT e m) where-  m >>= k =-    EitherT $-      runEitherT m-        >>= either-          (pure . Left)-          (runEitherT . k)+  m >>= k = eitherT left k m  instance MonadTrans (EitherT e) where   lift = EitherT . fmap Right@@ -95,9 +84,14 @@  -- Operations --- | Run a computation and get its result-anticipate :: (Monad m) => EitherT e m a -> EitherT e m (Either e a)-anticipate = lift . runEitherT+-- | Case analysis on the result of a computation+eitherT+  :: (Monad m)+  => (e -> EitherT e' m b) -- ^ Function applied in case of @Left e@+  -> (a -> EitherT e' m b) -- ^ Function applied in case of @Right a@+  -> EitherT e m a -- ^ Object of the case analysis+  -> EitherT e' m b+eitherT l r m = EitherT $ runEitherT m >>= runEitherT . either l r  -- | Terminate the computation with a value left :: (Applicative m) => e -> EitherT e m a
src/Mini/Transformers/MaybeT.hs view
@@ -7,7 +7,7 @@   runMaybeT,    -- * Operations-  anticipate,+  maybeT,   nothing,   just, ) where@@ -66,20 +66,10 @@  instance (Monad m) => Alternative (MaybeT m) where   empty = nothing-  m <|> n =-    MaybeT $-      runMaybeT m-        >>= maybe-          (runMaybeT n)-          (pure . Just)+  m <|> n = maybeT n just m  instance (Monad m) => Monad (MaybeT m) where-  m >>= k =-    MaybeT $-      runMaybeT m-        >>= maybe-          (pure Nothing)-          (runMaybeT . k)+  m >>= k = maybeT nothing k m  instance MonadTrans MaybeT where   lift = MaybeT . fmap Just@@ -92,9 +82,14 @@  -- Operations --- | Run a computation and get its result-anticipate :: (Monad m) => MaybeT m a -> MaybeT m (Maybe a)-anticipate = lift . runMaybeT+-- | Case analysis on the result of a computation+maybeT+  :: (Monad m)+  => MaybeT m b -- ^ Computation in case of @Nothing@+  -> (a -> MaybeT m b) -- ^ Function applied in case of @Just a@+  -> MaybeT m a -- ^ Object of the case analysis+  -> MaybeT m b+maybeT n j m = MaybeT $ runMaybeT m >>= runMaybeT . maybe n j  -- | Terminate the computation without a value nothing :: (Applicative m) => MaybeT m a