DAY 8
1
Software Development

## 具名函式的引用名稱

``````iex(0)> h Enum.map/2
# 會印出該函式的文件...
``````

## `&` 捕獲運算子 (capture operator)

``````/* JavaScript */

[-1, -2, 3].map(i => Math.abs(i))
// η-reduction
[-1, -2, 3].map(Math.abs)
``````

``````Enum.map([:a, :b, :c], fn a -> Atom.to_string(a) end)
# η-reduction
Enum.map([:a, :b, :c], &Atom.to_string/1)
``````

``````def double(i), do: i * 2
Enum.map([1, 2, 3], &double/1)
#=> [2, 4, 6]
``````

``````f = &Kernel.is_atom/1
f.(:atom) #=> true
``````

### 更短的匿名函式

``````Enum.map([1, 2, 3], fn i -> i * 2 end)
``````

``````Enum.map([1, 2, 3], &(&1 * 2))
#=> [2, 4, 6]
``````

### 更多參數

``````fn = &(&1 + &2 + &3)

fn.(1, 2, 3) #=> 6
``````

### 生成 List 或 Tuple

``````l = &[&1, &2]
l.(1, 2)
#=> [1, 2]

t = &{&1, &2}
t.(1, 2)
#=> {1, 2}
``````

### `&()` 的使用判準

``````Enum.group_by(["a", "b", "c", "a", "b"], &(&1))

#=> %{"a" => ["a", "a"], "b" => ["b", "b"], "c" => ["c"]}
``````

## 如果你傳了不夠的參數…

``````take_five = &Enum.take(&1, 5)
take_five.(1..100)

# => [1, 2, 3, 4, 5]
``````

partial application 常常一起提到的另一個詞叫 curry，柯里化。跟那種棕色的好吃食物沒有關係，這個字是說把接收 n 個參數的函式，轉換成 n 層只接收一個參數的函式

``````add_all = fn a -> fn b -> fn c ->  a + b + c end end end
#=> 6
``````

``````/* JavaScript */

add_all = a => b => c => a + b + c

#=> 6
``````

## 重點回顧

• `Module.function/arity` 來指稱一個函式
• 在 iex 裡用 `h/1` 可以印出函式說明
• `&` 運算子可以把具名函式轉成 lambda 來傳遞
• `&` 也可以用來寫出很短的函式
• `&` 還可以拿來做 partial application
• Elixir 對 curry 不太友善 (咦

Happy hacking! 明天見。