DAY 27
1
Software Development

## const

``````-- Haskell 語法
const :: a -> b -> a
const a b = a -- 已內建，只是秀出來讓你們羨慕一下

-- 使用
toOne = const 1

-- 呼叫
toOne "test" -- => 1
``````

``````// JavaScript 語法
let const = a => b => a //寫出來之後，發現好像也沒有多值得羨慕了

// 試試看
let toOne = const(1)

toOne(100) //=> 1
``````

``````# Elixir 語法
const = fn a -> fn b -> a end end

# 試試看
to_one = const.(1)

to_one.(999) #=> 1
``````

## Functor 的秀異之處：連續升格

``````-- Haskell 語法
things = [
Just "hello world",
Nothing,
Just "Elixir"
]
``````

``````-- Haskell 語法
toA = const 'A'
``````

### It's ...Showtime！

1. 把整個串列代換掉
``````toA things -- => 'A'
``````
1. 升格，改動串列內容，字母的串列會被印成字串
``````fmap toA things
-- => "AAAA"
``````
1. 升格兩次，改動 Maybe 的內容
``````(fmap . fmap) toA things
-- => [Just 'A', Nothing, Just 'A', Just 'A']
``````
1. 升格三次，改動字串的內容
``````(fmap . fmap . fmap) toA things
-- => [Just "AAAAAAAAAAA", Nothing, Just "AAAAAAA", Just "AAAAAA"]
``````

### 型別

``````-- Haskell 語法

fmap :: Functor f =>
(a -> b) -> f a -> f b

(fmap . fmap)
:: (Functor f1, Functor f2) =>
(a -> b) -> f1 (f2 a) -> f1 (f2 b)

(fmap . fmap . fmap)
:: (Functor f1, Functor f2, Functor f3) =>
(a -> b) -> f1 (f2 (f3 a)) -> f1 (f2 (f3 b))
``````

## 函式是一種 Functor 嗎？

``````-- Haskell
fmap f (\a -> b)
-- 會變成
\a -> f(b)
``````

``````-- Haskell 語法

fmap f g
--- 等同於
f . g
``````

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

-- 把最後兩個括起來會更加明顯：
(<\$>) @((->) _) :: (a -> b) -> (_ -> a) -> (_ -> b)

-- 跟函式組合(最後的部份加上括號)對比
(.)             :: (b -> c) -> (a -> b) -> (a -> c)
``````

### 驗證

``````-- Haskell 語法
f = (+1)
g = (*2)
h = (+3)

-- 封閉律與單位元素
fmp = fmap id f
fid = id f

f 1   -- => 2
fmp 1  -- => 2
fid 1 -- => 2

-- 分配律
hc = fmap (f . g) h
hd = fmap f . fmap g \$ h

hc 1 -- => 9
hd 1 -- => 9
``````

### 胡亂搞一通

``````fmap f fmap
-- 等同於
f . fmap
``````
``````fmap fmap fmap -- 嘿！？
-- 等同於
fmap . fmap
``````
``````fmap fmap \$ fmap fmap fmap -- 住、住手！
-- 等同於
fmap . fmap . fmap
``````

[to be continue]