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