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

Functional Ruby

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Functional Ruby

Avatar for 高見龍

高見龍

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