mini 1.6.0.0 → 1.6.1.0
raw patch · 10 files changed
+254/−9 lines, 10 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Mini.Hash.Class: class Hashable a
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Int.Int16
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Int.Int32
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Int.Int64
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Int.Int8
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Types.Bool
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Types.Char
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Types.Int
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Types.Word
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Word.Word16
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Word.Word32
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Word.Word64
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable GHC.Word.Word8
+ Mini.Hash.Class: instance Mini.Hash.Class.Hashable a => Mini.Hash.Class.Hashable [a]
+ Mini.Hash.Class: toBytes :: Hashable a => a -> [Word8]
+ 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
Files
- CHANGELOG.md +6/−0
- Mini/Hash/Class.hs +100/−0
- Mini/Hash/Murmur32.hs +136/−0
- Mini/Transformers/EitherT.hs +1/−1
- Mini/Transformers/MaybeT.hs +1/−1
- Mini/Transformers/ParserT.hs +1/−1
- Mini/Transformers/ReaderT.hs +1/−1
- Mini/Transformers/StateT.hs +1/−1
- Mini/Transformers/WriterT.hs +1/−1
- mini.cabal +6/−3
CHANGELOG.md view
@@ -1,3 +1,9 @@+1.6.1.0 [2026-02-10]+--------------------+* Create Mini.Hash.Class: The class of hashable types+* Create Mini.Hash.Murmur32: An implementation of MurmurHash3_x86_32 supporting+ incremental addition+ 1.6.0.0 [2025-04-27] -------------------- * Mini.Data.Recursion:
+ Mini/Hash/Class.hs view
@@ -0,0 +1,100 @@+-- | The class of hashable types+module Mini.Hash.Class (+ -- * Class+ Hashable (+ toBytes+ ),+) where++import Data.Bits (+ FiniteBits,+ finiteBitSize,+ shiftR,+ )+import Data.Int (+ Int,+ Int16,+ Int32,+ Int64,+ Int8,+ )+import Data.Word (+ Word,+ Word16,+ Word32,+ Word64,+ Word8,+ )+import Prelude (+ Bool,+ Char,+ Enum,+ Integral,+ concatMap,+ div,+ fmap,+ fromEnum,+ fromIntegral,+ iterate,+ pure,+ take,+ ($),+ (.),+ )++-- Class++-- | Instances should use little-endian byte order+class Hashable a where+ -- | Convert a hashable type to a sequence of bytes+ toBytes :: a -> [Word8]++instance Hashable Bool where+ toBytes = enumToBytes++instance Hashable Char where+ toBytes = enumToBytes++instance Hashable Int where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Int8 where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Int16 where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Int32 where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Int64 where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Word where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Word8 where+ toBytes = pure++instance Hashable Word16 where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Word32 where+ toBytes = finiteBitsIntegralToBytes++instance Hashable Word64 where+ toBytes = finiteBitsIntegralToBytes++instance (Hashable a) => Hashable [a] where+ toBytes = concatMap toBytes++-- Helpers++enumToBytes :: (Enum a) => a -> [Word8]+enumToBytes = pure . fromIntegral . fromEnum++finiteBitsIntegralToBytes :: (FiniteBits a, Integral a) => a -> [Word8]+finiteBitsIntegralToBytes w =+ take (finiteBitSize w `div` 8)+ . fmap fromIntegral+ $ iterate (`shiftR` 8) w
+ Mini/Hash/Murmur32.hs view
@@ -0,0 +1,136 @@+-- | An implementation of MurmurHash3_x86_32 supporting incremental addition+module Mini.Hash.Murmur32 (+ -- * Type+ Hash32,++ -- * Construction+ seed,++ -- * Operations+ add,+ digest,+) where++import Data.Bits (+ rotateL,+ shiftL,+ shiftR,+ xor,+ )+import Data.Function (+ on,+ )+import Data.Word (+ Word32,+ Word8,+ )+import Mini.Data.Recursion (+ bool,+ uncurry3,+ )+import Mini.Hash.Class (+ Hashable,+ toBytes,+ )+import Numeric (+ showHex,+ )+import Prelude (+ 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++instance Show Hash32 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++-- Helpers++addBytes :: [Word8] -> Hash32 -> Hash32+addBytes new (Hash32 h0 len0 old) = uncurry3 Hash32 $ go h0 len0 (old <> new)+ where+ go h len (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)++murmur :: Word32 -> Word32 -> Word32+murmur k1 h1 =+ let c1 = 0xcc9e2d51+ c2 = 0x1b873593+ c3 = 0xe6546b64+ k2 = k1 * c1+ k3 = k2 `rotateL` 15+ k4 = k3 * c2+ h2 = h1 `xor` k4+ h3 = h2 `rotateL` 13+ h4 = h3 * 5 + c3+ in h4++mix :: Word32 -> Word32+mix h1 =+ let h2 = h1 `xor` (h1 `shiftR` 16)+ h3 = h2 * 0x85ebca6b+ h4 = h3 `xor` (h3 `shiftR` 13)+ h5 = h4 * 0xc2b2ae35+ h6 = h5 `xor` (h5 `shiftR` 16)+ in h6
Mini/Transformers/EitherT.hs view
@@ -57,7 +57,7 @@ -- | A terminable transformer with termination /e/, inner monad /m/, return /a/ newtype EitherT e m a = EitherT { runEitherT :: m (Either e a)- -- ^ Unwrap an 'EitherT' computation+ -- ^ Unwrap a transformer computation } instance (Monad m) => Functor (EitherT e m) where
Mini/Transformers/MaybeT.hs view
@@ -55,7 +55,7 @@ -- | A terminable transformer with inner monad /m/, return /a/ newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a)- -- ^ Unwrap a 'MaybeT' computation+ -- ^ Unwrap a transformer computation } instance (Monad m) => Functor (MaybeT m) where
Mini/Transformers/ParserT.hs view
@@ -114,7 +114,7 @@ -- | A transformer parsing symbols /s/, inner monad /m/, return /a/ newtype ParserT s m a = ParserT { runParserT :: [s] -> m (Maybe (a, [s]))- -- ^ Unwrap a 'ParserT' computation with a sequence of symbols to parse+ -- ^ Unwrap a transformer computation with a sequence of symbols to parse } instance (Monad m) => Functor (ParserT s m) where
Mini/Transformers/ReaderT.hs view
@@ -48,7 +48,7 @@ -- | A transformer with read-only /r/, inner monad /m/, return /a/ newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a- -- ^ Unwrap a 'ReaderT' computation with an initial read-only value+ -- ^ Unwrap a transformer computation with an initial read-only value } instance (Monad m) => Functor (ReaderT r m) where
Mini/Transformers/StateT.hs view
@@ -53,7 +53,7 @@ -- | A transformer with state /s/, inner monad /m/, return /a/ newtype StateT s m a = StateT { runStateT :: s -> m (a, s)- -- ^ Unwrap a 'StateT' computation with an initial state+ -- ^ Unwrap a transformer computation with an initial state } instance (Monad m) => Functor (StateT s m) where
Mini/Transformers/WriterT.hs view
@@ -51,7 +51,7 @@ -- | A transformer with monoidal write-only /w/, inner monad /m/, return /a/ newtype WriterT w m a = WriterT { runWriterT :: m (a, w)- -- ^ Unwrap a 'WriterT' computation+ -- ^ Unwrap a transformer computation } instance (Monad m, Monoid w) => Functor (WriterT w m) where
mini.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: mini-version: 1.6.0.0+version: 1.6.1.0 license: MIT license-file: LICENSE author: Victor Wallsten <victor.wallsten@protonmail.com>@@ -9,14 +9,14 @@ bug-reports: https://gitlab.com/vicwall/mini/issues synopsis: Minimal essentials description:- Everyday essentials: data structures, primitive recursion, lenses,+ Everyday essentials: data structures, primitive recursion, hashing, lenses, transformers, and parsing. Uncompromisingly light on dependencies. Easily navigable code base, keeping indirection and clutter to a minimum. category: library-tested-with: GHC == 9.6.7+tested-with: GHC == 9.8.2 extra-doc-files: CHANGELOG.md extra-source-files: .editorconfig .hlint.yaml@@ -33,6 +33,8 @@ Mini.Data.Map Mini.Data.Recursion Mini.Data.Set+ Mini.Hash.Class+ Mini.Hash.Murmur32 Mini.Optics.Lens Mini.Transformers.Class Mini.Transformers.EitherT@@ -58,3 +60,4 @@ -Wmissing-import-lists -Wpartial-fields -Wredundant-constraints+ -haddock