DAY 26
1
Software Development

## 串列是一種 Functor 嗎？

``````-- Haskell 語法
(<\$>) @ [] :: (a -> b) -> [a] -> [b]

map (+1) [1, 2, 3] -- => [2, 3, 4] -- 把串列當做…嗯…串列

fmap (+1) [1, 2, 3] -- => [2, 3, 4] -- 把串列當做一種 Functor
``````

## 字串是一種 Functor 嗎？

### 二元組是一種 Functor 嗎？

``````-- Haskell 語法
(<\$>) @ ((,) _) :: (a -> b) -> (_, a) -> (_, b)

fmap (+1) (1, 10) -- => (1, 11)
``````

## 三元組、四元組……是一種 Functor 嗎？

``````(<\$>) @ ((,,) _ _)
:: Functor ((,,) _1 _2) =>
(a -> b) -> (_1, _2, a) -> (_1, _2, b)

fmap (+10) (1, 2, 3) -- => (1, 2, 13)
``````

## Maybe 是一種 Functor 嗎？

``````-- Haskell 語法
(<\$>) @ Maybe :: (a -> b) -> Maybe a -> Maybe b

fmap (+1) (Just 1) -- => Just 2

fmap (+1) Nothing -- => Nothing
``````

## Either 是一種 Functor 嗎？

``````-- Haskell 語法
(<\$>) @ Either e :: (a -> b) -> E e a -> E e b

fmap (+1) (Right 10) -- => Right 11

fmap (+1) (Left "Something went Wrong!") -- => Left "Something went Wrong!"
``````

## Sum 是一種 Functor 嗎？

``````-- Haskell 語法
(<\$>) @ Sum :: (a -> b) -> Sum a -> Sum b

fmap (* 10) (Sum 2) -- => Sum {getSum = 20}
``````

## 抽象：不在乎是什麼容器

``````-- Haskell 語法

-- map 也可以將函式升格
g = map (+1)

g [1, 2, 3] -- => [2, 3, 4]

g \$ Sum 1 -- 然而只能用在串列上，在其它型別上會出錯
-- <interactive>:10:5: error:
• Data constructor not in scope: Sum :: Integer -> [b]

-- 可以用在各種 functor 上的升格函式

addOne [1, 2, 3] -- => [2, 3, 4]

addOne \$ Sum 1   -- => Sum {getSum = 2}

addOne \$ Just 1  -- => Just 2
addOne \$ Nothing -- => Nothing

addOne \$ Right 10 -- => Right 11
addOne \$ Left 1   -- => Left 1

addOne \$ (1, 2)        -- => (1, 3)
addOne \$ (1, 2, 3)     -- => (1, 2, 4)
addOne \$ (1, 2, 3, 4)  -- => (1, 2, 3, 5)
``````

## 小訣竅：怎麼看函式的型別

``````-- Haskell 語法

Prelude> :set -XTypedApplications

Prelude> :t fmap @ Maybe
fmap @ Maybe :: (a -> b) -> Maybe a -> Maybe b

Prelude> :t (<\$>) @ []
(<\$>) @ [] :: (a -> b) -> [a] -> [b]

Prelude> :t (<\$>) @ ((,,,,) _ _ _ _)
(<\$>) @ ((,,,,) _ _ _ _)
:: Functor ((,,,,) _1 _2 _3 _4) =>
(a -> b) -> (_1, _2, _3, _4, a) -> (_1, _2, _3, _4, b)
``````

[to be continue]