# 11.3　Identity和Const

``````newtype Identity a = Identity { runIdentity :: a }

Identity 3 :: Identity Int

runIdentity \$ Identity 3
-- 3
``````

``````instance Functor Identity where
fmap f idx = Identity (f (runIdentity idx))
-- point-free写法
fmap f = Identity . f . runIdentity
fmap (+1) (Identity 3)
-- Identity 4
``````

``````fmap id (Identity 3) == id (Identity 3)
fmap ((+1) . (*2)) (Identity 3) == (fmap (+1) . fmap (*2)) (Identity 3)
``````

``````newtype Const a b = Const { getConst :: a }
Const 3 :: Const Int String
Const 3 :: Const Int Int
...
getConst (Const 3)
-- 3
``````

``````Prelude> import Control.Applicative
Prelude Control.Applicative> Const 3 == Const 3
True
Prelude Control.Applicative> (Const 3 :: Const Int Int) == (Const 3 :: Const Int String)

<interactive>:5:32:
Couldn't match type ‘[Char]’ with ‘Int’
Expected type: Const Int Int
Actual type: Const Int String
In the second argument of ‘(==)’, namely
‘(Const 3 :: Const Int String)’
In the expression:
(Const 3 :: Const Int Int) == (Const 3 :: Const Int String)
In an equation for ‘it’:
it = (Const 3 :: Const Int Int) == (Const 3 :: Const Int String)
``````

`````` type Foo a = Int
(3 :: Foo String) == (3 :: Foo Char)
-- (3 :: Int) == (3 :: Int)
-- True
``````

``````instance Functor (Const a) where
fmap f c = c
``````

Const a代表了盒子抽象的另一个极端。这是一个什么都没有装的空盒子，通过幻影类型，Const a b给你产生了盒子里装有一个b类型的值的幻觉，但实际上这个值根本不存在，而对这个盒子做fmap的结果相当于什么都不做，原封不动地把盒子返回即可。有兴趣的读者可以验证下，它是否满足函子的两个约束呢？

× 454
× 1756
× 2438
× 965
× 1
× 1
× 1208
× 0
× 1
× 0
× 2
× 1
× 3
× 4
× 2764
× 818
× 1109