ee8be9c8fa9cff974ce5c4c8d2ac7e051088b638
[packages/transformers.git] / Data / Functor / Reverse.hs
1 {-# LANGUAGE CPP #-}
2 #if __GLASGOW_HASKELL__ >= 702
3 {-# LANGUAGE Safe #-}
4 #endif
5 #if __GLASGOW_HASKELL__ >= 706
6 {-# LANGUAGE PolyKinds #-}
7 #endif
8 #if __GLASGOW_HASKELL__ >= 710
9 {-# LANGUAGE AutoDeriveTypeable #-}
10 #endif
11 -----------------------------------------------------------------------------
12 -- |
13 -- Module : Data.Functor.Reverse
14 -- Copyright : (c) Russell O'Connor 2009
15 -- License : BSD-style (see the file LICENSE)
16 --
17 -- Maintainer : R.Paterson@city.ac.uk
18 -- Stability : experimental
19 -- Portability : portable
20 --
21 -- Making functors whose elements are notionally in the reverse order
22 -- from the original functor.
23 -----------------------------------------------------------------------------
24
25 module Data.Functor.Reverse (
26 Reverse(..),
27 ) where
28
29 import Control.Applicative.Backwards
30 import Data.Functor.Classes
31
32 import Prelude hiding (foldr, foldr1, foldl, foldl1, null, length)
33 import Control.Applicative
34 import Data.Foldable
35 import Data.Traversable
36 import Data.Monoid
37
38 -- | The same functor, but with 'Foldable' and 'Traversable' instances
39 -- that process the elements in the reverse order.
40 newtype Reverse f a = Reverse { getReverse :: f a }
41
42 instance (Eq1 f) => Eq1 (Reverse f) where
43 liftEq eq (Reverse x) (Reverse y) = liftEq eq x y
44 {-# INLINE liftEq #-}
45
46 instance (Ord1 f) => Ord1 (Reverse f) where
47 liftCompare comp (Reverse x) (Reverse y) = liftCompare comp x y
48 {-# INLINE liftCompare #-}
49
50 instance (Read1 f) => Read1 (Reverse f) where
51 liftReadsPrec rp rl = readsData $
52 readsUnaryWith (liftReadsPrec rp rl) "Reverse" Reverse
53
54 instance (Show1 f) => Show1 (Reverse f) where
55 liftShowsPrec sp sl d (Reverse x) =
56 showsUnaryWith (liftShowsPrec sp sl) "Reverse" d x
57
58 instance (Eq1 f, Eq a) => Eq (Reverse f a) where (==) = eq1
59 instance (Ord1 f, Ord a) => Ord (Reverse f a) where compare = compare1
60 instance (Read1 f, Read a) => Read (Reverse f a) where readsPrec = readsPrec1
61 instance (Show1 f, Show a) => Show (Reverse f a) where showsPrec = showsPrec1
62
63 -- | Derived instance.
64 instance (Functor f) => Functor (Reverse f) where
65 fmap f (Reverse a) = Reverse (fmap f a)
66 {-# INLINE fmap #-}
67
68 -- | Derived instance.
69 instance (Applicative f) => Applicative (Reverse f) where
70 pure a = Reverse (pure a)
71 {-# INLINE pure #-}
72 Reverse f <*> Reverse a = Reverse (f <*> a)
73 {-# INLINE (<*>) #-}
74
75 -- | Derived instance.
76 instance (Alternative f) => Alternative (Reverse f) where
77 empty = Reverse empty
78 {-# INLINE empty #-}
79 Reverse x <|> Reverse y = Reverse (x <|> y)
80 {-# INLINE (<|>) #-}
81
82 -- | Fold from right to left.
83 instance (Foldable f) => Foldable (Reverse f) where
84 foldMap f (Reverse t) = getDual (foldMap (Dual . f) t)
85 {-# INLINE foldMap #-}
86 foldr f z (Reverse t) = foldl (flip f) z t
87 {-# INLINE foldr #-}
88 foldl f z (Reverse t) = foldr (flip f) z t
89 {-# INLINE foldl #-}
90 foldr1 f (Reverse t) = foldl1 (flip f) t
91 {-# INLINE foldr1 #-}
92 foldl1 f (Reverse t) = foldr1 (flip f) t
93 {-# INLINE foldl1 #-}
94 #if MIN_VERSION_base(4,8,0)
95 null (Reverse t) = null t
96 length (Reverse t) = length t
97 #endif
98
99 -- | Traverse from right to left.
100 instance (Traversable f) => Traversable (Reverse f) where
101 traverse f (Reverse t) =
102 fmap Reverse . forwards $ traverse (Backwards . f) t
103 {-# INLINE traverse #-}