diff options
Diffstat (limited to 'libraries/base/GHC')
-rw-r--r-- | libraries/base/GHC/Base.lhs | 203 | ||||
-rw-r--r-- | libraries/base/GHC/Conc/Sync.lhs | 12 | ||||
-rw-r--r-- | libraries/base/GHC/Event/Array.hs | 2 | ||||
-rw-r--r-- | libraries/base/GHC/Event/EPoll.hsc | 1 | ||||
-rw-r--r-- | libraries/base/GHC/Event/Internal.hs | 1 | ||||
-rw-r--r-- | libraries/base/GHC/Event/Manager.hs | 1 | ||||
-rw-r--r-- | libraries/base/GHC/Event/Poll.hsc | 1 | ||||
-rw-r--r-- | libraries/base/GHC/Event/TimerManager.hs | 1 | ||||
-rw-r--r-- | libraries/base/GHC/GHCi.hs | 9 | ||||
-rw-r--r-- | libraries/base/GHC/ST.lhs | 4 |
10 files changed, 221 insertions, 14 deletions
diff --git a/libraries/base/GHC/Base.lhs b/libraries/base/GHC/Base.lhs index 1c8e144b7f..6d0c4b12d5 100644 --- a/libraries/base/GHC/Base.lhs +++ b/libraries/base/GHC/Base.lhs @@ -129,6 +129,8 @@ infixl 4 <$ infixl 1 >>, >>= infixr 0 $ +infixl 4 <*>, <*, *>, <**> + default () -- Double isn't available yet \end{code} @@ -159,10 +161,102 @@ foldr = error "urk" -} \end{code} +%********************************************************* +%* * +\subsection{Monoids} +%* * +%********************************************************* +\begin{code} + +-- --------------------------------------------------------------------------- +-- | The class of monoids (types with an associative binary operation that +-- has an identity). Instances should satisfy the following laws: +-- +-- * @mappend mempty x = x@ +-- +-- * @mappend x mempty = x@ +-- +-- * @mappend x (mappend y z) = mappend (mappend x y) z@ +-- +-- * @mconcat = 'foldr' mappend mempty@ +-- +-- The method names refer to the monoid of lists under concatenation, +-- but there are many other instances. +-- +-- Minimal complete definition: 'mempty' and 'mappend'. +-- +-- Some types can be viewed as a monoid in more than one way, +-- e.g. both addition and multiplication on numbers. +-- In such cases we often define @newtype@s and make those instances +-- of 'Monoid', e.g. 'Sum' and 'Product'. + +class Monoid a where + mempty :: a + -- ^ Identity of 'mappend' + mappend :: a -> a -> a + -- ^ An associative operation + mconcat :: [a] -> a + + -- ^ Fold a list using the monoid. + -- For most types, the default definition for 'mconcat' will be + -- used, but the function is included in the class definition so + -- that an optimized version can be provided for specific types. + + mconcat = foldr mappend mempty + +instance Monoid [a] where + mempty = [] + mappend = (++) + +instance Monoid b => Monoid (a -> b) where + mempty _ = mempty + mappend f g x = f x `mappend` g x + +instance Monoid () where + -- Should it be strict? + mempty = () + _ `mappend` _ = () + mconcat _ = () + +instance (Monoid a, Monoid b) => Monoid (a,b) where + mempty = (mempty, mempty) + (a1,b1) `mappend` (a2,b2) = + (a1 `mappend` a2, b1 `mappend` b2) + +instance (Monoid a, Monoid b, Monoid c) => Monoid (a,b,c) where + mempty = (mempty, mempty, mempty) + (a1,b1,c1) `mappend` (a2,b2,c2) = + (a1 `mappend` a2, b1 `mappend` b2, c1 `mappend` c2) + +instance (Monoid a, Monoid b, Monoid c, Monoid d) => Monoid (a,b,c,d) where + mempty = (mempty, mempty, mempty, mempty) + (a1,b1,c1,d1) `mappend` (a2,b2,c2,d2) = + (a1 `mappend` a2, b1 `mappend` b2, + c1 `mappend` c2, d1 `mappend` d2) + +instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e) => + Monoid (a,b,c,d,e) where + mempty = (mempty, mempty, mempty, mempty, mempty) + (a1,b1,c1,d1,e1) `mappend` (a2,b2,c2,d2,e2) = + (a1 `mappend` a2, b1 `mappend` b2, c1 `mappend` c2, + d1 `mappend` d2, e1 `mappend` e2) + +-- lexicographical ordering +instance Monoid Ordering where + mempty = EQ + LT `mappend` _ = LT + EQ `mappend` y = y + GT `mappend` _ = GT + +instance Monoid a => Applicative ((,) a) where + pure x = (mempty, x) + (u, f) <*> (v, x) = (u `mappend` v, f x) +\end{code} + %********************************************************* %* * -\subsection{Monadic classes @Functor@, @Monad@ } +\subsection{Monadic classes @Functor@, @Applicative@, @Monad@ } %* * %********************************************************* @@ -186,6 +280,82 @@ class Functor f where (<$) :: a -> f b -> f a (<$) = fmap . const +-- | A functor with application, providing operations to +-- +-- * embed pure expressions ('pure'), and +-- +-- * sequence computations and combine their results ('<*>'). +-- +-- A minimal complete definition must include implementations of these +-- functions satisfying the following laws: +-- +-- [/identity/] +-- +-- @'pure' 'id' '<*>' v = v@ +-- +-- [/composition/] +-- +-- @'pure' (.) '<*>' u '<*>' v '<*>' w = u '<*>' (v '<*>' w)@ +-- +-- [/homomorphism/] +-- +-- @'pure' f '<*>' 'pure' x = 'pure' (f x)@ +-- +-- [/interchange/] +-- +-- @u '<*>' 'pure' y = 'pure' ('$' y) '<*>' u@ +-- +-- The other methods have the following default definitions, which may +-- be overridden with equivalent specialized implementations: +-- +-- * @u '*>' v = 'pure' ('const' 'id') '<*>' u '<*>' v@ +-- +-- * @u '<*' v = 'pure' 'const' '<*>' u '<*>' v@ +-- +-- As a consequence of these laws, the 'Functor' instance for @f@ will satisfy +-- +-- * @'fmap' f x = 'pure' f '<*>' x@ +-- +-- If @f@ is also a 'Monad', it should satisfy +-- +-- * @'pure' = 'return'@ +-- +-- * @('<*>') = 'ap'@ +-- +-- (which implies that 'pure' and '<*>' satisfy the applicative functor laws). + +class Functor f => Applicative f where + -- | Lift a value. + pure :: a -> f a + + -- | Sequential application. + (<*>) :: f (a -> b) -> f a -> f b + + -- | Sequence actions, discarding the value of the first argument. + (*>) :: f a -> f b -> f b + (*>) = liftA2 (const id) + + -- | Sequence actions, discarding the value of the second argument. + (<*) :: f a -> f b -> f a + (<*) = liftA2 const + +-- | A variant of '<*>' with the arguments reversed. +(<**>) :: Applicative f => f a -> f (a -> b) -> f b +(<**>) = liftA2 (flip ($)) + +-- | 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 f a = pure f <*> a + +-- | Lift a binary function to actions. +liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c +liftA2 f a b = (fmap f a) <*> b + +-- | Lift a ternary function to actions. +liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d +liftA3 f a b c = (fmap f a) <*> b <*> c + {- | The 'Monad' class defines the basic operations over a /monad/, a concept from a branch of mathematics known as /category theory/. From the perspective of a Haskell programmer, however, it is best to @@ -209,37 +379,52 @@ The instances of 'Monad' for lists, 'Data.Maybe.Maybe' and 'System.IO.IO' defined in the "Prelude" satisfy these laws. -} -class Monad m where +class Applicative m => Monad m where -- | Sequentially compose two actions, passing any value produced -- by the first as an argument to the second. (>>=) :: forall a b. m a -> (a -> m b) -> m b + m >>= f = join (fmap f m) + -- | Sequentially compose two actions, discarding any value produced -- by the first, like sequencing operators (such as the semicolon) -- in imperative languages. (>>) :: forall a b. m a -> m b -> m b + (>>) = (*>) + {-# INLINE (>>) #-} + + join :: m (m a) -> m a + join m = m >>= id + -- Explicit for-alls so that we know what order to -- give type arguments when desugaring -- | Inject a value into the monadic type. return :: a -> m a + return = pure + -- | Fail with a message. This operation is not part of the -- mathematical definition of a monad, but is invoked on pattern-match -- failure in a @do@ expression. fail :: String -> m a - - {-# INLINE (>>) #-} - m >> k = m >>= \_ -> k fail s = error s + +-- instances for Prelude types + instance Functor ((->) r) where fmap = (.) +instance Applicative ((->) a) where + pure = const + (<*>) f g x = f x (g x) + instance Monad ((->) r) where return = const f >>= k = \ r -> k (f r) r instance Functor ((,) a) where fmap f (x,y) = (x, f y) + \end{code} @@ -253,6 +438,10 @@ instance Functor ((,) a) where instance Functor [] where fmap = map +instance Applicative [] where + pure = return + (<*>) = liftA2 id + instance Monad [] where m >>= k = foldr ((++) . k) [] m m >> k = foldr ((++) . (\ _ -> k)) [] m @@ -601,6 +790,10 @@ asTypeOf = const instance Functor IO where fmap f x = x >>= (return . f) +instance Applicative IO where + pure = return + (<*>) = liftA2 id + instance Monad IO where {-# INLINE return #-} {-# INLINE (>>) #-} diff --git a/libraries/base/GHC/Conc/Sync.lhs b/libraries/base/GHC/Conc/Sync.lhs index ebb7226d09..6a14b4d6af 100644 --- a/libraries/base/GHC/Conc/Sync.lhs +++ b/libraries/base/GHC/Conc/Sync.lhs @@ -548,6 +548,10 @@ unSTM (STM a) = a instance Functor STM where fmap f x = x >>= (return . f) +instance Applicative STM where + pure = return + (<*>) = liftA2 id + instance Monad STM where {-# INLINE return #-} {-# INLINE (>>) #-} @@ -571,9 +575,13 @@ thenSTM (STM m) k = STM ( \s -> returnSTM :: a -> STM a returnSTM x = STM (\s -> (# s, x #)) +instance Alternative STM where + empty = retry + (<|>) = orElse + instance MonadPlus STM where - mzero = retry - mplus = orElse + mzero = empty + mplus = (<|>) -- | Unsafely performs IO in the STM monad. Beware: this is a highly -- dangerous thing to do. diff --git a/libraries/base/GHC/Event/Array.hs b/libraries/base/GHC/Event/Array.hs index 30dbd77f5b..3626387669 100644 --- a/libraries/base/GHC/Event/Array.hs +++ b/libraries/base/GHC/Event/Array.hs @@ -24,7 +24,7 @@ module GHC.Event.Array , useAsPtr ) where -import Control.Monad hiding (forM_) +import Control.Monad hiding (forM_, empty) import Data.Bits ((.|.), shiftR) import Data.IORef (IORef, atomicModifyIORef', newIORef, readIORef, writeIORef) import Data.Maybe diff --git a/libraries/base/GHC/Event/EPoll.hsc b/libraries/base/GHC/Event/EPoll.hsc index b808b21e96..298f450096 100644 --- a/libraries/base/GHC/Event/EPoll.hsc +++ b/libraries/base/GHC/Event/EPoll.hsc @@ -41,7 +41,6 @@ available = False import Control.Monad (when) import Data.Bits (Bits, FiniteBits, (.|.), (.&.)) import Data.Maybe (Maybe(..)) -import Data.Monoid (Monoid(..)) import Data.Word (Word32) import Foreign.C.Error (eNOENT, getErrno, throwErrno, throwErrnoIfMinus1, throwErrnoIfMinus1_) diff --git a/libraries/base/GHC/Event/Internal.hs b/libraries/base/GHC/Event/Internal.hs index a4c2e10d32..fcd7886a20 100644 --- a/libraries/base/GHC/Event/Internal.hs +++ b/libraries/base/GHC/Event/Internal.hs @@ -25,7 +25,6 @@ module GHC.Event.Internal import Data.Bits ((.|.), (.&.)) import Data.List (foldl', intercalate) import Data.Maybe (Maybe(..)) -import Data.Monoid (Monoid(..)) import Foreign.C.Error (eINTR, getErrno, throwErrno) import System.Posix.Types (Fd) import GHC.Base diff --git a/libraries/base/GHC/Event/Manager.hs b/libraries/base/GHC/Event/Manager.hs index d55d5b1193..53788137ac 100644 --- a/libraries/base/GHC/Event/Manager.hs +++ b/libraries/base/GHC/Event/Manager.hs @@ -56,7 +56,6 @@ import Data.Bits ((.&.)) import Data.IORef (IORef, atomicModifyIORef', mkWeakIORef, newIORef, readIORef, writeIORef) import Data.Maybe (Maybe(..), maybe) -import Data.Monoid (mappend, mconcat, mempty) import GHC.Arr (Array, (!), listArray) import GHC.Base import GHC.Conc.Signal (runHandlers) diff --git a/libraries/base/GHC/Event/Poll.hsc b/libraries/base/GHC/Event/Poll.hsc index bb0b6e570b..4a27fcc3f4 100644 --- a/libraries/base/GHC/Event/Poll.hsc +++ b/libraries/base/GHC/Event/Poll.hsc @@ -28,7 +28,6 @@ import Control.Concurrent.MVar (MVar, newMVar, swapMVar) import Control.Monad ((=<<), liftM, liftM2, unless) import Data.Bits (Bits, FiniteBits, (.|.), (.&.)) import Data.Maybe (Maybe(..)) -import Data.Monoid (Monoid(..)) import Data.Word import Foreign.C.Types (CInt(..), CShort(..)) import Foreign.Ptr (Ptr) diff --git a/libraries/base/GHC/Event/TimerManager.hs b/libraries/base/GHC/Event/TimerManager.hs index f94f06148a..a3734fc473 100644 --- a/libraries/base/GHC/Event/TimerManager.hs +++ b/libraries/base/GHC/Event/TimerManager.hs @@ -42,7 +42,6 @@ import Control.Monad ((=<<), liftM, sequence_, when) import Data.IORef (IORef, atomicModifyIORef', mkWeakIORef, newIORef, readIORef, writeIORef) import Data.Maybe (Maybe(..)) -import Data.Monoid (mempty) import GHC.Base import GHC.Conc.Signal (runHandlers) import GHC.Num (Num(..)) diff --git a/libraries/base/GHC/GHCi.hs b/libraries/base/GHC/GHCi.hs index f66d540574..8436837c88 100644 --- a/libraries/base/GHC/GHCi.hs +++ b/libraries/base/GHC/GHCi.hs @@ -21,7 +21,7 @@ module GHC.GHCi {-# WARNING "This is an unstable interface." #-} ( GHCiSandboxIO(..), NoIO() ) where -import GHC.Base (IO(), Monad, (>>=), return, id, (.)) +import GHC.Base (IO(), Monad, Functor(fmap), Applicative(..), (>>=), liftA2, return, id, (.)) -- | A monad that can execute GHCi statements by lifting them out of -- m into the IO monad. (e.g state monads) @@ -34,6 +34,13 @@ instance GHCiSandboxIO IO where -- | A monad that doesn't allow any IO. newtype NoIO a = NoIO { noio :: IO a } +instance Functor NoIO where + fmap f (NoIO a) = NoIO (fmap f a) + +instance Applicative NoIO where + pure = return + (<*>) = liftA2 id + instance Monad NoIO where return a = NoIO (return a) (>>=) k f = NoIO (noio k >>= noio . f) diff --git a/libraries/base/GHC/ST.lhs b/libraries/base/GHC/ST.lhs index 5da8b0afed..8c7b4a6eee 100644 --- a/libraries/base/GHC/ST.lhs +++ b/libraries/base/GHC/ST.lhs @@ -65,6 +65,10 @@ instance Functor (ST s) where case (m s) of { (# new_s, r #) -> (# new_s, f r #) } +instance Applicative (ST s) where + pure = return + (<*>) = liftA2 id + instance Monad (ST s) where {-# INLINE return #-} {-# INLINE (>>) #-} |