Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Ruby

Functional Ruby

高見龍

June 27, 2023
Tweet

More Decks by 高見龍

Other Decks in Technology

Transcript

  1. ޒഒላӃ +4 // JavaScript const list = [1, 2, 3,

    4, 5] const odd_numbers = [] // 挑出奇數 for (let i = 0; i < list.length; i++) { const el = list[i] if (el % 2 === 1) { odd_numbers.push(el) } } const triple_numbers = [] // 乘 3 倍 for (let i = 0; i < odd_numbers.length; i++) { triple_numbers.push(odd_numbers[i] * 3) } let total = 0 // 計算總和 for (let i = 0; i < triple_numbers.length; i++) { total += triple_numbers[i] } console.log(total) // 27
  2. ޒഒላӃ +4 // JavaScript const list = [1, 2, 3,

    4, 5] const result = list.filter(i => i % 2 === 1) .map(i => i * 3) .reduce((acc, cv) => acc + cv, 0) console.log(result) // 27
  3. ޒഒላӃ +4 // JavaScript const list = [1, 2, 3,

    4, 5] const oddOnly = (i) => i % 2 === 1 const triple = (i) => i * 3 const sum = (acc, cv) => acc + cv const result = list.filter(oddOnly) .map(triple) .reduce(sum, 0) console.log(result) // 27
  4. ޒഒላӃ +4 # 不純 def replace_element(arr, idx, value) arr[idx] =

    value arr end list = [1, 2, 3] result = replace_element(list, 0, "a") p result # ["a", 2, 3] p list # ???
  5. ޒഒላӃ +4 # 比較純 def replace_element(arr, idx, value) dup_arr =

    arr.dup dup_arr[idx] = value dup_arr end list = [1, 2, 3] result = replace_element(list, 0, "a") p result # ["a", 2, 3] p list # ???
  6. ޒഒላӃ +4 // JavaScript const list = [1, 2, 3]

    const otherList = list console.log(list) // [1, 2, 3] otherList[0] = "a" console.log(list) // ???
  7. ޒഒላӃ +4 // Rust fn main() { let list =

    [1, 2, 3]; list[0] = 100; // 預設是不能修改的 println!("{:?}", list); }
  8. ޒഒላӃ +4 # Elixir list = [1, 2, 3] list[0]

    = 100 # 預設是不可修改的
  9. ޒഒላӃ +4 list = [1, 2, 3, 4, 5] double_list

    = list.map { |n| 2 * n } odd_numbers = list.filter { |n| n.odd? } p double_list # [2, 4, 6, 8, 10] p odd_numbers # [1, 3, 5]
  10. ޒഒላӃ +4 // JavaScript const list = [1, 2, 3,

    4, 5] const oddOnly = (i) => i % 2 === 1 const triple = (i) => i * 3 const sum = (acc, cv) => acc + cv const result = list.filter(oddOnly) .map(triple) .reduce(sum, 0) console.log(result) // 27
  11. ޒഒላӃ +4 # 把⽅法物件化 def add(a, b) a + b

    end m1 = method(:add) m2 = Proc.new { |x, y| add(x, y) } m3 = -> (x, y) { add(x, y) } puts m1.call(1, 2) # 3 puts m2.call(3, 4) # 7 puts m3.call(5, 6) # 11
  12. ޒഒላӃ +4 # Data.define 是 Ruby 3.2 之後才加進來的新功能 Location =

    Data.define(:x, :y) point = Location.new(0, 0) puts point.x, point.y point.x = 100 # 錯誤
  13. ޒഒላӃ +4 def add_numbers(a, b, c) a + b +

    c end # 柯⾥化 curried_add = -> (x) { -> (y) { -> (z) { add_numbers(x, y, z) } } }
  14. ޒഒላӃ +4 # 分開寫 add_2 = curried_add.call(2) add_3 = add_2.call(3)

    result = add_3.call(5) puts result # 或串在⼀起寫 puts curried_add.call(2).call(3).call(5)
  15. ޒഒላӃ +4 def add_numbers(a, b, c) a + b +

    c end 
 # 柯⾥化 # curried_add = -> (x) { # -> (y) { # -> (z) { # add_numbers(x, y, z) # } # } # } # Ruby 內建的⽅法 curried_add = method(:add_numbers).curry
  16. ޒഒላӃ +4 def add_numbers(a, b, c) a + b +

    c end # Partial Function # 先給 1 個參數 add_2 = -> (i, j) { add_numbers(2, i, j) } # 剩下的 2 個參數之後再⼀次給⾜ puts add_2.call(3, 5) # 10
  17. ޒഒላӃ +4 def add_numbers(a, b, c) a + b +

    c end # Partial Function # 或是先給 2 個參數 add_2_and_3 = -> (k) { add_numbers(2, 3, k) } # 最後 1 個參數之後再給 puts add_2_and_3.call(5) # 10
  18. ޒഒላӃ +4 def add_numbers(a, b, c) a + b +

    c end # 利⽤內建的 curry ⽅法 partial_fn = method(:add_numbers).curry # 先給 1 個參數 add_2 = partial_fn.call(2) # 剩下的參數之後再⼀次給⾜ puts add_2.call(3, 5) # 10
  19. ޒഒላӃ +4 // JavaScript const add_one = (n) => n

    + 1 const double = (n) => n * 2 const square = (n) => n * n console.log(square(double(add_one(5)))) // 144
  20. ޒഒላӃ +4 # Elixir add_one = fn x -> x

    + 1 end double = fn x -> x * 2 end square = fn x -> x * x end result = 5 |> add_one.() |> double.() |> square.() IO.inspect result # 144
  21. ޒഒላӃ +4 add_one = -> (n) { n + 1

    } double = -> (n) { n * 2 } square = -> (n) { n * n } # 先加 1,再加倍,最後再平⽅ composed_fn = add_one.compose(double) .compose(square) puts composed_fn.call(5) # 144
  22. ޒഒላӃ +4 add_one = -> (n) { n + 1

    } double = -> (n) { n * 2 } square = -> (n) { n * n } # 先加 1,再加倍,最後再平⽅ composed_fn = add_one >> double >> square puts composed_fn.call(5) # 144