belgian-structured-communication 0.1.0.0 → 0.2.0.0
raw patch · 3 files changed
+32/−17 lines, 3 filesdep +randomPVP ok
version bump matches the API change (PVP)
Dependencies added: random
API changes (from Hackage documentation)
+ Finance.Belgium.StructuredCommunication: instance System.Random.Internal.Uniform Finance.Belgium.StructuredCommunication.StructuredCommunication
+ Finance.Belgium.StructuredCommunication: instance System.Random.Internal.UniformRange Finance.Belgium.StructuredCommunication.StructuredCommunication
+ Finance.Belgium.StructuredCommunication: instance System.Random.Random Finance.Belgium.StructuredCommunication.StructuredCommunication
Files
- CHANGELOG.md +4/−0
- belgian-structured-communication.cabal +2/−1
- src/Finance/Belgium/StructuredCommunication.hs +26/−16
CHANGELOG.md view
@@ -8,6 +8,10 @@ ## Unreleased +## 0.2.0.0 - 2025-01-26++Make `StructuredCommunication` an instance of `Random`, `Uniform` and `UniformRange`.+ ## 0.1.0.0 - 2023-06-17 Initial version with parser, instance for `Eq`, `Enum`, `Ord`, `Show`, `Integral` and `Real`.
belgian-structured-communication.cabal view
@@ -1,5 +1,5 @@ name: belgian-structured-communication-version: 0.1.0.0+version: 0.2.0.0 synopsis: parsing, rendering and manipulating the structured communication of Belgian financial transactions. description: A package that exports a 'StructuredCommunication' data type that can render and manipulate structured@@ -28,6 +28,7 @@ , hashable >= 1.0 , parsec >=3.0 , QuickCheck >=2.1+ , random >=1.2 , template-haskell >=2.3.0.0 , text >= 0.1 , validity >= 0.4.0.0
src/Finance/Belgium/StructuredCommunication.hs view
@@ -71,6 +71,8 @@ #else import Language.Haskell.TH.Syntax (Exp (AppE, ConE, LitE), Lift (lift), Lit (IntegerL), Pat (ConP, LitP)) #endif+import System.Random (Random)+import System.Random.Internal (Uniform (uniformM), UniformRange (uniformRM)) import Test.QuickCheck.Arbitrary (Arbitrary (arbitrary)) import Test.QuickCheck.Gen (choose) import Text.Parsec (ParseError)@@ -84,10 +86,10 @@ -- checksum is not valid. The module thus aims to prevent parsing, changing, etc. 'StructuredCommunication' objects into an invalid state. data StructuredCommunication = StructuredCommunication !Word16 !Word16 !Word32 deriving (Data, Eq, Generic, Ord, Read, Typeable) -_maxVal :: Integral a => a+_maxVal :: (Integral a) => a _maxVal = 9999999999 -_numVals :: Integral a => a+_numVals :: (Integral a) => a _numVals = 10000000000 _fromEnum :: StructuredCommunication -> Int64@@ -118,6 +120,14 @@ _both :: (a -> b) -> (a, a) -> (b, b) _both f ~(x, y) = (f x, f y) +instance Random StructuredCommunication++instance Uniform StructuredCommunication where+ uniformM g = _toEnum <$> uniformRM (0, _maxVal) g++instance UniformRange StructuredCommunication where+ uniformRM (s0, s1) g = _toEnum <$> uniformRM (_fromEnum s0, _fromEnum s1) g+ instance Real StructuredCommunication where toRational = toRational . toInteger @@ -143,7 +153,7 @@ Word32 checksum (StructuredCommunication _ _ v₂) = v₂ `mod` 100 -_rcheck :: Integral i => Integer -> i -> Bool+_rcheck :: (Integral i) => Integer -> i -> Bool _rcheck mx = go where go v = 0 <= i && i <= mx where i = fromIntegral v@@ -253,23 +263,23 @@ go 0 v = pure v go n v = digit >>= go (n - 1) . ((10 * v) +) . fromIntegral . digitToInt -_char3 :: Stream s m Char => Char -> ParsecT s u m Char+_char3 :: (Stream s m Char) => Char -> ParsecT s u m Char _char3 c = c' <* c' <* c' where c' = char c -_presuf :: Stream s m Char => ParsecT s u m Char+_presuf :: (Stream s m Char) => ParsecT s u m Char _presuf = try (_char3 '+') <|> _char3 '*' -_slash :: Stream s m Char => ParsecT s u m Char+_slash :: (Stream s m Char) => ParsecT s u m Char _slash = _space *> char '/' <* _space -_space :: Stream s m Char => ParsecT s u m ()+_space :: (Stream s m Char) => ParsecT s u m () _space = skipMany space -- | A 'ParsecT' that parses a string into a 'StructuredCommunication', the 'StructuredCommunication' can be invalid. The parser also does /not/ (per se) ends with an 'eof'. communicationParser' ::- Stream s m Char =>+ (Stream s m Char) => -- | The 'ParsecT' object that parses the structured communication of the form @+++000\/0000\/00097+++@. ParsecT s u m StructuredCommunication communicationParser' = do@@ -281,28 +291,28 @@ -- | A 'ParsecT' that parses a string into a 'StructuredCommunication', the 'StructuredCommunication' is checked for its validity (checksum). The parser does /not/ (per se) ends with an 'eof'. communicationParser ::- Stream s m Char =>+ (Stream s m Char) => -- | The 'ParsecT' object that parses the structured communication of the form @+++000\/0000\/00097+++@. ParsecT s u m StructuredCommunication communicationParser = communicationParser' >>= _liftEither . prettyValidate -- | A 'ParsecT' that parses a string into a 'StructuredCommunication', the 'StructuredCommunication' can be invalid. The parser also checks if this is the end of the stream. communicationEParser' ::- Stream s m Char =>+ (Stream s m Char) => -- | The 'ParsecT' object that parses the structured communication of the form @+++000\/0000\/00097+++@. ParsecT s u m StructuredCommunication communicationEParser' = communicationParser <* eof -- | A 'ParsecT' that parses a string into a 'StructuredCommunication', the 'StructuredCommunication' is checked for its validity (checksum). The parser also checks that this is the end of the stream. communicationEParser ::- Stream s m Char =>+ (Stream s m Char) => -- | The 'ParsecT' object that parses the structured communication of the form @+++000\/0000\/00097+++@. ParsecT s u m StructuredCommunication communicationEParser = communicationEParser' >>= _liftEither . prettyValidate -- | Parsing a stream into a 'StructuredCommunication' that also validates the checksum of the communication. The stream does not per se needs to end with structured communcation. parseCommunication ::- Stream s Identity Char =>+ (Stream s Identity Char) => -- | The stream that is parsed into a 'StructuredCommunication' s -> -- | The result of parsing, either a 'StructuredCommunication' wrapped in a 'Right' or a parsing error wrapped in a 'Left'.@@ -311,7 +321,7 @@ -- | Parsing a stream into a 'StructuredCommunication' that does /noet/ validate the checksum of the communication. The stream does not per se needs to end with structured communcation. parseCommunication' ::- Stream s Identity Char =>+ (Stream s Identity Char) => -- | The stream that is parsed into a 'StructuredCommunication' s -> -- | The result of parsing, either a 'StructuredCommunication' wrapped in a 'Right' or a parsing error wrapped in a 'Left'.@@ -320,7 +330,7 @@ -- | Parsing a stream into a 'StructuredCommunication' that also validates the checksum of the communication. After the structured communication, the stream needs to end. parseCommunicationE ::- Stream s Identity Char =>+ (Stream s Identity Char) => -- | The stream that is parsed into a 'StructuredCommunication' s -> -- | The result of parsing, either a 'StructuredCommunication' wrapped in a 'Right' or a parsing error wrapped in a 'Left'.@@ -329,14 +339,14 @@ -- | Parsing a stream into a 'StructuredCommunication' that does /noet/ validate the checksum of the communication. After the structured communication, the stream needs to end. parseCommunicationE' ::- Stream s Identity Char =>+ (Stream s Identity Char) => -- | The stream that is parsed into a 'StructuredCommunication' s -> -- | The result of parsing, either a 'StructuredCommunication' wrapped in a 'Right' or a parsing error wrapped in a 'Left'. Either ParseError StructuredCommunication parseCommunicationE' = runParser communicationEParser' () "" -_liftEither :: Show s => MonadFail m => Either s a -> m a+_liftEither :: (Show s) => (MonadFail m) => Either s a -> m a _liftEither = either (fail . show) pure _toPattern :: StructuredCommunication -> Pat