# 11.1　容器抽象

``````Maybe a = Just a | Nothing

Just 3 :: Maybe Int
Nothing :: Maybe a
``````

``````addOneMaybe :: Maybe Int -> Maybe Int
addOneMaybe (Just a) = Just (a + 1)

-- 4
-- Nothing
``````

``````addOneList :: [Int] -> [Int]
-- [2,3,4]
``````

``````someFunction :: f a -> f b
``````

``````someFunction :: a -> b
``````

``````fmap :: (a -> b) -> f a -> f b
``````

``````fmap :: (a -> b) -> [a] -> [b]
fmap = map

fmap :: (a -> b) -> Maybe a -> Maybe b
fmap f (Just a) = Just (f a)
fmap _ Nothing = Nothing
``````

``````class Functor f where
fmap :: (a -> b) -> f a -> f b
``````

``````instance Functor [] where
fmap = map

instance Functor Maybe where
fmap f (Just a) = Just (f a)
fmap _ Nothing = Nothing
``````

``````Prelude> fmap (+1) (Just 10)
Just 11
Prelude> fmap (+1) Nothing
Nothing
Prelude> fmap (+1) [1,2,3]
[2,3,4]
Prelude> fmap (+1) []
[]
Prelude> take 3 \$ fmap (+1) (repeat 1)
[2,2,2]

instance Functor ((,) a) where
fmap f (x, y) = (x, f y)

fmap (+1) (2,3)
-- (2,4)
``````

(a,b)是类型(,) a b的语法糖，我们把元组的第二个元素，也就是类型是b的元素当作盒子里等待处理的元素，而把(,) a当成一整个盒子，所以实例声明的时候是instance Functor ((,) a)，代表(,) a这一整个类型是函子。当我们把函数通过fmap作用到双元组时，我们其实只是把函数作用在第二个元素上面而已。

``````instance Functor ((->) a) where
fmap = ???
``````

``````fmap :: (b -> c) -> ((->) a b) -> ((->) a c)
-- 也就是
fmap :: (b -> c) -> (a -> b) -> (a -> c)
instance Functor ((->) a) where
fmap f fa = f . fa
-- 或者
fmap = (.)
fmap (*2) (+1)
-- \x -> (x + 1) * 2
fmap (*2) (+1) \$ 3
-- 8
``````

× 453
× 1756
× 2438
× 958
× 1
× 1
× 1198
× 0
× 1
× 0
× 2
× 1
× 3
× 4
× 2754
× 817
× 1107