Functor is now a superclass of Applicative, and Functor and Foldable
are now superclasses of Traversable. The new hierarchy makes clear the
inclusions between the classes, but means more work in defining instances.
Default definitions are provided to help.
-- This module describes a structure intermediate between a functor and
-- a monad: it provides pure expressions and sequencing, but no binding.
-- (Technically, a strong lax monoidal functor.) For more details, see
-- This module describes a structure intermediate between a functor and
-- a monad: it provides pure expressions and sequencing, but no binding.
-- (Technically, a strong lax monoidal functor.) For more details, see
+-- /Applicative Programming with Effects/,
+-- by Conor McBride and Ross Paterson, online at
-- <http://www.soi.city.ac.uk/~ross/papers/Applicative.html>.
--
-- This interface was introduced for parsers by Niklas Röjemo, because
-- <http://www.soi.city.ac.uk/~ross/papers/Applicative.html>.
--
-- This interface was introduced for parsers by Niklas Röjemo, because
-- * Instances
WrappedMonad(..), Const(..), ZipList(..),
-- * Utility functions
-- * Instances
WrappedMonad(..), Const(..), ZipList(..),
-- * Utility functions
- (<$), (*>), (<*), (<**>),
+ (<$>), (<$), (*>), (<*), (<**>),
liftA, liftA2, liftA3
) where
liftA, liftA2, liftA3
) where
#endif
import Control.Monad (liftM, ap)
#endif
import Control.Monad (liftM, ap)
+import Control.Monad.Instances ()
import Data.Monoid (Monoid(..))
infixl 4 <$>, <$
import Data.Monoid (Monoid(..))
infixl 4 <$>, <$
-- [/interchange/]
-- @u '<*>' 'pure' y = 'pure' ('$' y) '<*>' u@
--
-- [/interchange/]
-- @u '<*>' 'pure' y = 'pure' ('$' y) '<*>' u@
--
--- [/pure application/]
--- @f '<$>' v = 'pure' f '<*>' v@
---
--- Minimal complete definition: 'pure' and '<*>'.
---
--- If @f@ is also a 'Functor', define @('<$>') = 'fmap'@.
--- If it is also a 'Monad', define @'pure' = 'return'@ and @('<*>') = 'ap'@.
+-- If @f@ is also a 'Monad', define @'pure' = 'return'@ and @('<*>') = 'ap'@.
-class Applicative f where
+class Functor f => Applicative f where
-- | Lift a value.
pure :: a -> f a
-- | Sequential application.
(<*>) :: f (a -> b) -> f a -> f b
-- | Lift a value.
pure :: a -> f a
-- | Sequential application.
(<*>) :: f (a -> b) -> f a -> f b
- -- | Map a function over an action.
- (<$>) :: (a -> b) -> f a -> f b
- f <$> v = pure f <*> v
-
-- instances for Prelude types
instance Applicative Maybe where
-- instances for Prelude types
instance Applicative Maybe where
pure = const
(<*>) f g x = f x (g x)
pure = const
(<*>) f g x = f x (g x)
+instance Monoid a => Applicative ((,) a) where
+ pure x = (mempty, x)
+ (u, f) <*> (v, x) = (u `mappend` v, f x)
+
-- new instances
newtype WrappedMonad m a = WrapMonad { unwrapMonad :: m a }
-- new instances
newtype WrappedMonad m a = WrapMonad { unwrapMonad :: m a }
+instance Monad m => Functor (WrappedMonad m) where
+ fmap f (WrapMonad v) = WrapMonad (liftM f v)
+
instance Monad m => Applicative (WrappedMonad m) where
pure = WrapMonad . return
WrapMonad f <*> WrapMonad v = WrapMonad (f `ap` v)
instance Monad m => Applicative (WrappedMonad m) where
pure = WrapMonad . return
WrapMonad f <*> WrapMonad v = WrapMonad (f `ap` v)
- f <$> WrapMonad v = WrapMonad (liftM f v)
newtype Const a b = Const { getConst :: a }
newtype Const a b = Const { getConst :: a }
+instance Functor (Const m) where
+ fmap _ (Const v) = Const v
+
instance Monoid m => Applicative (Const m) where
pure _ = Const mempty
Const f <*> Const v = Const (f `mappend` v)
instance Monoid m => Applicative (Const m) where
pure _ = Const mempty
Const f <*> Const v = Const (f `mappend` v)
- _ <$> Const v = Const v
-- | Lists, but with an 'Applicative' functor based on zipping, so that
--
-- | Lists, but with an 'Applicative' functor based on zipping, so that
--
--
newtype ZipList a = ZipList { getZipList :: [a] }
--
newtype ZipList a = ZipList { getZipList :: [a] }
+instance Functor ZipList where
+ fmap f (ZipList xs) = ZipList (map f xs)
+
instance Applicative ZipList where
pure x = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)
instance Applicative ZipList where
pure x = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)
- f <$> ZipList xs = ZipList (map f xs)
+-- | A synonym for 'fmap'.
+(<$>) :: Functor f => (a -> b) -> f a -> f b
+f <$> a = fmap f a
+
-(<$) :: Applicative f => a -> f b -> f a
+(<$) :: Functor f => a -> f b -> f a
(<$) = (<$>) . const
-- | Sequence actions, discarding the value of the first argument.
(<$) = (<$>) . const
-- | Sequence actions, discarding the value of the first argument.
(<**>) :: Applicative f => f a -> f (a -> b) -> f b
(<**>) = liftA2 (flip ($))
(<**>) :: Applicative f => f a -> f (a -> b) -> f b
(<**>) = liftA2 (flip ($))
--- | A synonym for '<$>'.
+-- | Lift a function to actions.
+-- This function may be used as a value for `fmap` in a `Functor` instance.
liftA :: Applicative f => (a -> b) -> f a -> f b
liftA :: Applicative f => (a -> b) -> f a -> f b
+liftA f a = pure f <*> a
-- | Lift a binary function to actions.
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
-- | Lift a binary function to actions.
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
import qualified Data.List as List
import Data.Monoid (Monoid(..))
import Data.Typeable
import qualified Data.List as List
import Data.Monoid (Monoid(..))
import Data.Typeable
-import Control.Applicative (Applicative(..))
+import Control.Applicative (Applicative(..), (<$>))
import Data.Traversable (Traversable(traverse))
import Data.Foldable (Foldable(foldMap))
import Data.Traversable (Traversable(traverse))
import Data.Foldable (Foldable(foldMap))
null, length, take, drop, splitAt, foldl, foldl1, foldr, foldr1,
reverse)
import qualified Data.List (foldl')
null, length, take, drop, splitAt, foldl, foldl1, foldr, foldr1,
reverse)
import qualified Data.List (foldl')
-import Control.Applicative (Applicative(..))
+import Control.Applicative (Applicative(..), (<$>))
import Control.Monad (MonadPlus(..))
import Data.Monoid (Monoid(..))
import Data.Foldable
import Control.Monad (MonadPlus(..))
import Data.Monoid (Monoid(..))
import Data.Foldable
newtype Seq a = Seq (FingerTree (Elem a))
instance Functor Seq where
newtype Seq a = Seq (FingerTree (Elem a))
instance Functor Seq where
+ fmap f (Seq xs) = Seq (fmap (fmap f) xs)
instance Foldable Seq where
foldr f z (Seq xs) = foldr (flip (foldr f)) z xs
instance Foldable Seq where
foldr f z (Seq xs) = foldr (flip (foldr f)) z xs
foldl1 f (Deep _ pr m sf) =
foldl f (foldl (foldl f) (foldl1 f pr) m) sf
foldl1 f (Deep _ pr m sf) =
foldl f (foldl (foldl f) (foldl1 f pr) m) sf
+instance Functor FingerTree where
+ fmap _ Empty = Empty
+ fmap f (Single x) = Single (f x)
+ fmap f (Deep v pr m sf) =
+ Deep v (fmap f pr) (fmap (fmap f) m) (fmap f sf)
+
instance Traversable FingerTree where
traverse _ Empty = pure Empty
traverse f (Single x) = Single <$> f x
instance Traversable FingerTree where
traverse _ Empty = pure Empty
traverse f (Single x) = Single <$> f x
foldl1 f (Three a b c) = (a `f` b) `f` c
foldl1 f (Four a b c d) = ((a `f` b) `f` c) `f` d
foldl1 f (Three a b c) = (a `f` b) `f` c
foldl1 f (Four a b c d) = ((a `f` b) `f` c) `f` d
+instance Functor Digit where
+ fmap = fmapDefault
+
instance Traversable Digit where
traverse f (One a) = One <$> f a
traverse f (Two a b) = Two <$> f a <*> f b
instance Traversable Digit where
traverse f (One a) = One <$> f a
traverse f (Two a b) = Two <$> f a <*> f b
foldl f z (Node2 _ a b) = (z `f` a) `f` b
foldl f z (Node3 _ a b c) = ((z `f` a) `f` b) `f` c
foldl f z (Node2 _ a b) = (z `f` a) `f` b
foldl f z (Node3 _ a b c) = ((z `f` a) `f` b) `f` c
+instance Functor Node where
+ fmap = fmapDefault
+
instance Traversable Node where
traverse f (Node2 v a b) = Node2 v <$> f a <*> f b
traverse f (Node3 v a b c) = Node3 v <$> f a <*> f b <*> f c
instance Traversable Node where
traverse f (Node2 v a b) = Node2 v <$> f a <*> f b
traverse f (Node3 v a b c) = Node3 v <$> f a <*> f b <*> f c
--
-- Class of data structures that can be traversed from left to right.
--
--
-- Class of data structures that can be traversed from left to right.
--
--- See also <http://www.soi.city.ac.uk/~ross/papers/Applicative.html>.
+-- See also /Applicative Programming with Effects/,
+-- by Conor McBride and Ross Paterson, online at
+-- <http://www.soi.city.ac.uk/~ross/papers/Applicative.html>.
module Data.Traversable (
Traversable(..),
module Data.Traversable (
Traversable(..),
fmapDefault,
foldMapDefault,
) where
fmapDefault,
foldMapDefault,
) where
import Prelude hiding (mapM, sequence)
import qualified Prelude (mapM)
import Control.Applicative
import Prelude hiding (mapM, sequence)
import qualified Prelude (mapM)
import Control.Applicative
+import Data.Foldable (Foldable)
import Data.Monoid (Monoid)
import Data.Array
-- | Functors representing data structures that can be traversed from
-- left to right.
--
import Data.Monoid (Monoid)
import Data.Array
-- | Functors representing data structures that can be traversed from
-- left to right.
--
--- Minimal complete definition: 'traverse'.
+-- Minimal complete definition: 'traverse' or 'sequenceA'.
--
-- Instances are similar to 'Functor', e.g. given a data type
--
--
-- Instances are similar to 'Functor', e.g. given a data type
--
-- This is suitable even for abstract types, as the laws for '<*>'
-- imply a form of associativity.
--
-- This is suitable even for abstract types, as the laws for '<*>'
-- imply a form of associativity.
--
-class Traversable t where
+class (Functor t, Foldable t) => Traversable t where
-- | Map each element of a structure to an action, evaluate
-- these actions from left to right, and collect the results.
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
-- | Map each element of a structure to an action, evaluate
-- these actions from left to right, and collect the results.
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
+ traverse f = sequenceA . fmap f
+
+ -- | Evaluate each action in the structure from left to right,
+ -- and collect the results.
+ sequenceA :: Applicative f => t (f a) -> f (t a)
+ sequenceA = traverse id
-- | Map each element of a structure to an monadic action, evaluate
-- these actions from left to right, and collect the results.
mapM :: Monad m => (a -> m b) -> t a -> m (t b)
mapM f = unwrapMonad . traverse (WrapMonad . f)
-- | Map each element of a structure to an monadic action, evaluate
-- these actions from left to right, and collect the results.
mapM :: Monad m => (a -> m b) -> t a -> m (t b)
mapM f = unwrapMonad . traverse (WrapMonad . f)
+ -- | Evaluate each monadic action in the structure from left to right,
+ -- and collect the results.
+ sequence :: Monad m => t (m a) -> m (t a)
+ sequence = mapM id
+
-- instances for Prelude types
instance Traversable Maybe where
-- instances for Prelude types
instance Traversable Maybe where
--- | Evaluate each action in the structure from left to right,
--- and collect the results.
-sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
-sequenceA = traverse id
-
--- | Evaluate each monadic action in the structure from left to right,
--- and collect the results.
-sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
-sequence = mapM id
-
--- | Any 'Traversable' can also be made an instance of 'Functor' by
--- defining 'fmap' as 'fmapDefault'.
+-- | This function may be used as a value for `fmap` in a `Functor` instance.
fmapDefault :: Traversable t => (a -> b) -> t a -> t b
fmapDefault f = getId . traverse (Id . f)
fmapDefault :: Traversable t => (a -> b) -> t a -> t b
fmapDefault f = getId . traverse (Id . f)
--- | Any 'Traversable' can also be made an instance of
--- 'Data.Foldable.Foldable' by defining 'Data.Foldable.foldMap'
--- as 'foldMapDefault'.
+-- | This function may be used as a value for `Data.Foldable.foldMap`
+-- in a `Foldable` instance.
foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> t a -> m
foldMapDefault f = getConst . traverse (Const . f)
foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> t a -> m
foldMapDefault f = getConst . traverse (Const . f)
newtype Id a = Id { getId :: a }
newtype Id a = Id { getId :: a }
+instance Functor Id where
+ fmap f (Id x) = Id (f x)
+
instance Applicative Id where
pure = Id
Id f <*> Id x = Id (f x)
instance Applicative Id where
pure = Id
Id f <*> Id x = Id (f x)
-import Control.Applicative (Applicative(..))
+import Control.Applicative (Applicative(..), (<$>))
import Control.Monad
import Data.Monoid (Monoid(..))
import Data.Sequence (Seq, empty, singleton, (<|), (|>), fromList,
import Control.Monad
import Data.Monoid (Monoid(..))
import Data.Sequence (Seq, empty, singleton, (<|), (|>), fromList,