Identity.hs 3.68 KB
Newer Older
1
{-# LANGUAGE DeriveDataTypeable #-}
2
{-# LANGUAGE DeriveGeneric #-}
3
{-# LANGUAGE DeriveTraversable #-}
Fumiaki Kinoshita's avatar
Fumiaki Kinoshita committed
4
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5
{-# LANGUAGE Trustworthy #-}
6

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Functor.Identity
-- Copyright   :  (c) Andy Gill 2001,
--                (c) Oregon Graduate Institute of Science and Technology 2001
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  ross@soi.city.ac.uk
-- Stability   :  experimental
-- Portability :  portable
--
-- The identity functor and monad.
--
-- This trivial type constructor serves two purposes:
--
-- * It can be used with functions parameterized by functor or monad classes.
--
-- * It can be used as a base monad to which a series of monad
--   transformers may be applied to construct a composite monad.
--   Most monad transformer modules include the special case of
--   applying the transformer to 'Identity'.  For example, @State s@
--   is an abbreviation for @StateT s 'Identity'@.
--
30
-- @since 4.8.0.0
31 32 33 34 35 36 37
-----------------------------------------------------------------------------

module Data.Functor.Identity (
    Identity(..),
  ) where

import Control.Monad.Fix
38
import Control.Monad.Zip
39
import Data.Bits (Bits, FiniteBits)
40
import Data.Coerce
41
import Data.Data (Data)
42
import Data.Foldable
43 44
import Data.Ix (Ix)
import Data.Semigroup (Semigroup)
45
import Data.String (IsString)
46
import Foreign.Storable (Storable)
47
import GHC.Generics (Generic, Generic1)
48 49 50

-- | Identity functor and monad. (a non-strict monad)
--
51
-- @since 4.8.0.0
52
newtype Identity a = Identity { runIdentity :: a }
53 54 55
    deriving ( Bits, Bounded, Data, Enum, Eq, FiniteBits, Floating, Fractional
             , Generic, Generic1, Integral, IsString, Ix, Monoid, Num, Ord
             , Real, RealFrac, RealFloat , Semigroup, Storable, Traversable)
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

-- | This instance would be equivalent to the derived instances of the
-- 'Identity' newtype if the 'runIdentity' field were removed
instance (Read a) => Read (Identity a) where
    readsPrec d = readParen (d > 10) $ \ r ->
        [(Identity x,t) | ("Identity",s) <- lex r, (x,t) <- readsPrec 11 s]

-- | This instance would be equivalent to the derived instances of the
-- 'Identity' newtype if the 'runIdentity' field were removed
instance (Show a) => Show (Identity a) where
    showsPrec d (Identity x) = showParen (d > 10) $
        showString "Identity " . showsPrec 11 x

-- ---------------------------------------------------------------------------
-- Identity instances for Functor and Monad

instance Foldable Identity where
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
    foldMap                = coerce

    elem                   = (. runIdentity) #. (==)
    foldl                  = coerce
    foldl'                 = coerce
    foldl1 _               = runIdentity
    foldr f z (Identity x) = f x z
    foldr'                 = foldr
    foldr1 _               = runIdentity
    length _               = 1
    maximum                = runIdentity
    minimum                = runIdentity
    null _                 = False
    product                = runIdentity
    sum                    = runIdentity
    toList (Identity x)    = [x]
89

90 91
instance Functor Identity where
    fmap     = coerce
92 93

instance Applicative Identity where
94 95
    pure     = Identity
    (<*>)    = coerce
96 97 98 99 100

instance Monad Identity where
    m >>= k  = k (runIdentity m)

instance MonadFix Identity where
101 102
    mfix f   = Identity (fix (runIdentity . f))

103 104 105
instance MonadZip Identity where
    mzipWith = coerce
    munzip   = coerce
106 107 108 109 110 111

-- | Internal (non-exported) 'Coercible' helper for 'elem'
--
-- See Note [Function coercion] in "Data.Foldable" for more details.
(#.) :: Coercible b c => (b -> c) -> (a -> b) -> a -> c
(#.) _f = coerce