1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
#if __GLASGOW_HASKELL__ >= 703
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif
-- |
-- Module : Data.Vector.Fusion.Stream.Size
-- Copyright : (c) Roman Leshchinskiy 2008-2010
-- License : BSD-style
--
-- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
-- Stability : experimental
-- Portability : portable
--
-- Size hints for streams.
--
module Data.Vector.Fusion.Stream.Size (
Size(..), smaller, larger, toMax, upperBound
) where
import Data.Vector.Fusion.Util ( delay_inline )
-- | Size hint
data Size = Exact Int -- ^ Exact size
| Max Int -- ^ Upper bound on the size
| Unknown -- ^ Unknown size
deriving( Eq, Show )
instance Num Size where
Exact m + Exact n = Exact (m+n)
Exact m + Max n = Max (m+n)
Max m + Exact n = Max (m+n)
Max m + Max n = Max (m+n)
_ + _ = Unknown
Exact m - Exact n = Exact (m-n)
Exact m - Max n = Max m
Max m - Exact n = Max (m-n)
Max m - Max n = Max m
Max m - Unknown = Max m
_ - _ = Unknown
fromInteger n = Exact (fromInteger n)
-- | Minimum of two size hints
smaller :: Size -> Size -> Size
{-# INLINE smaller #-}
smaller (Exact m) (Exact n) = Exact (delay_inline min m n)
smaller (Exact m) (Max n) = Max (delay_inline min m n)
smaller (Exact m) Unknown = Max m
smaller (Max m) (Exact n) = Max (delay_inline min m n)
smaller (Max m) (Max n) = Max (delay_inline min m n)
smaller (Max m) Unknown = Max m
smaller Unknown (Exact n) = Max n
smaller Unknown (Max n) = Max n
smaller Unknown Unknown = Unknown
-- | Maximum of two size hints
larger :: Size -> Size -> Size
{-# INLINE larger #-}
larger (Exact m) (Exact n) = Exact (delay_inline max m n)
larger (Exact m) (Max n) | m >= n = Exact m
| otherwise = Max n
larger (Max m) (Exact n) | n >= m = Exact n
| otherwise = Max m
larger (Max m) (Max n) = Max (delay_inline max m n)
larger _ _ = Unknown
-- | Convert a size hint to an upper bound
toMax :: Size -> Size
toMax (Exact n) = Max n
toMax (Max n) = Max n
toMax Unknown = Unknown
-- | Compute the minimum size from a size hint
lowerBound :: Size -> Int
lowerBound (Exact n) = n
lowerBound _ = 0
-- | Compute the maximum size from a size hint if possible
upperBound :: Size -> Maybe Int
upperBound (Exact n) = Just n
upperBound (Max n) = Just n
upperBound Unknown = Nothing
|