packages feed

mmsyn2-array (empty) → 0.1.0.0

raw patch · 5 files changed

+195/−0 lines, 5 filesdep +basesetup-changed

Dependencies added: base

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for mmsyn2-array++## 0.1.0.0 -- 2020-12-14++* First version. Released on an unsuspecting world.
+ CaseBi/Arr.hs view
@@ -0,0 +1,143 @@+{-# OPTIONS_HADDOCK show-extensions #-}+{-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Module    :  CaseBi.Arr+-- Copyright   :  (c) OleksandrZhabenko 2019+-- License     :  MIT+-- Stability   :  Experimental+-- Maintainer  :  olexandr543@yahoo.com+--+-- A library that can be used as a @case ... of@ constuction analogue for the multiple @Ord a => a -> b@+-- transformations and data representation. Uses 'Array' internally. If you use the module in GHCi, then, please,+-- run the interpreter with the flag -fobject-code.+--++module CaseBi.Arr (+{- |  * Functions that can be used instead of @case ... of@ construction+@+case var of+ a1 -> b1+ a2 -> b2+ a3 -> b3+ ...+ an -> bn+ _  -> def+@+for efficiency or other data representation+-}+  -- * Basic functions+  getBFst''+  , getBFst'+  -- * With a transformation to the array+  , listArrSortedByFst+  , getBFstLSorted'+  , getBFstL'+) where++import qualified Data.List as L (sortBy)+import GHC.Arr+import Data.Ord (comparing)++{- | The function that can be used instead of the 'case ... of' function+@+case var of+ a1 -> b1+ a2 -> b2+ a3 -> b3+ ...+ an -> bn+ _  -> defaultValue+@+If we follow a lot of teaching materials that explain the workflow of the construction+we think that the complexity of it is about /O(n)/ for the transformation of @a@ to @b@ here.+David Feuer (david.feuer (at) gmail.com) said that 'case ... of' is already optimized in GHC.+Some benchmarks show that its behaviour  tends to be about of /O(log n)/ complexity, the same as+the proposed function 'getBFst''. Nevertheless, the last one shows better performance in some situations,+is rather general and can be used for another data representation. Therefore, it can be preferred in+some situations. 'getBFst'' uses binary search algorithm and an 'Array' of @(a, b)@ as somewhat like a complicated filter or like a special sieve. The array must be sorted in ascending order here for the algorithm to be used correctly. For this you can use the function 'listArrSortedBy' or the similar ones.+The function 'getBFst''' is used internally in the 'getBFst'' that is recommended to be used in most cases. Nevertheless,+it is provided here if you have precomputed the first two arguments or at least some parts of them so that+you can reduce the needed amount of computations in the 'getBFst''.+-}+getBFst''+  :: Ord a => (# Int, (a, b) #) -- ^ The first unboxed tuple of the index and the element of the array.+  -> (# Int, (a, b) #) -- ^ The second unboxed tuple of the index and the element of the array.+  -> Array i (a, b) -- ^ The array of the pairs of the compared value and the result that is used in case the last argument is equal to the compared value.+  -> b -- ^ The default value that is used if no first element in the array tuples equals to the compared value.+  -> a -- ^ The compared value, well, the @main@ function argument, to which it is applied.+  -> b -- ^ The resulting branch value.+getBFst'' (# i, k #) (# j, m #) arr def x+ | x > fst k && x < fst m = gBF3 (# i, k #) (# j, m #) arr def x+ | otherwise = def+{-# INLINE getBFst'' #-}++-- | The meaning of the arguments is the same as for 'getBFst'''. Is used internally in it.+gBF3 :: Ord a => (# Int, (a, b) #) -> (# Int, (a, b) #) -> Array i (a, b) -> b -> a -> b+gBF3 (# i, k #) (# j, m #) arr def x+ | j - i > 1 = let !n = (i + j) `quot` 2 in let !p = unsafeAt arr n in+    case compare x (fst p) of+     GT -> gBF3 (# n, p #) (# j, m #) arr def x+     EQ -> snd p+     _  -> gBF3 (# i, k #) (# n, p #) arr def x+ | x == fst m = snd m+ | x == fst k = snd k+ | otherwise = def+{-# INLINABLE gBF3 #-}++-- | A generally written without extending variant of the 'getBFst'''.+getBFst' :: Ord a => (b, Array Int (a, b)) -> a -> b+getBFst' (def, arr) = getBFst'' (# i, k #) (# j, m #) arr def+  where (!i,!j) = bounds arr+        !k = unsafeAt arr i+        !m = unsafeAt arr j+{-# INLINE getBFst' #-}++{- | If the list argument is sorted in the ascending order by the first element in every tuple, then to reduce+computations instead of+@+\def xs x -> getBFst' (def, listArray (0,length xs - 1) xs) x+@+you can use this function.+-}+getBFstLSorted'+  :: Ord a => b+  -> [(a, b)]+  -> a+  -> b+getBFstLSorted' def xs = getBFst'' (# 0, k #) (# l, m #) arr def+  where !l = length xs - 1+        !arr = listArray (0,l) xs+        !k = unsafeAt arr 0+        !m = unsafeAt arr l+{-# INLINE getBFstLSorted' #-}++{- | If it is unknown whether the list argument is sorted in the ascending order by the first element in every+tuple (or, definitely, it is not, speaking generally), then instead of+@+\def xs x -> getBFst' (def, listArray (0,length xs - 1) . sortBy (comparing fst) $ xs) x+@+you can use this function.+-}+getBFstL'+  :: Ord a => b+  -> [(a, b)]+  -> a+  -> b+getBFstL' def xs = getBFst'' (# 0, k #) (# l, m #) arr def+  where !l = length xs - 1+        !arr = listArray (0,l) . L.sortBy (comparing fst) $ xs+        !k = unsafeAt arr 0+        !m = unsafeAt arr l+{-# INLINE getBFstL' #-}++{- | Sorts the list of pairs by the first element in the tuples, then transforms them into an immutable array. Can be+used only if the list contains no more than 2^31 - 1 elements though this is not checked, it is up to user+to check this constraint before or provide its correctness by design.+-}+listArrSortedByFst :: Ord a => [(a,b)] -> Array Int (a,b)+listArrSortedByFst xs = listArray (0,l - 1) ys+  where !ys = L.sortBy (comparing fst) xs+        !l = length ys+{-# INLINE listArrSortedByFst #-}
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2020 OleksandrZhabenko++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ mmsyn2-array.cabal view
@@ -0,0 +1,25 @@+-- Initial mmsyn2-array.cabal generated by cabal init.  For further+-- documentation, see http://haskell.org/cabal/users-guide/++name:                mmsyn2-array+version:             0.1.0.0+synopsis:            A library with less dependencies that can be used for multiple @Ord a => a -> b@ transformations.+description:         A library that can be used as a @case ... of@ constuction analogue for the multiple @Ord a => a -> b@ transformations and data representation. Uses "GHC.Arr" internally. If you use the module in GHCi, then, please, run the interpreter with the flag -fobject-code.+homepage:            https://hackage.haskell.org/package/mmsyn2-array+license:             MIT+license-file:        LICENSE+author:              OleksandrZhabenko+maintainer:          olexandr543@yahoo.com+copyright:           Oleksandr Zhabenko+category:            Development, Data, Language+build-type:          Simple+extra-source-files:  CHANGELOG.md+cabal-version:       >=1.10++library+  exposed-modules:     CaseBi.Arr+  -- other-modules:+  other-extensions:    UnboxedTuples, BangPatterns, FlexibleContexts+  build-depends:       base >=4.7 && <4.15+  -- hs-source-dirs:+  default-language:    Haskell2010