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 +7/−0
- mini.cabal +1/−1
- src/Mini/Hash/Class.hs +16/−3
- src/Mini/Hash/Murmur32.hs +49/−65
- src/Mini/Random/Class.hs +0/−15
- src/Mini/Transformers/EitherT.hs +11/−17
- src/Mini/Transformers/MaybeT.hs +11/−16
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