Slide 1

Slide 1 text

為你⾃⼰學 系列單元 ޒഒላӃ Functional Ruby

Slide 2

Slide 2 text

ޒഒላӃ വᏐࣜఔࣜઃܭ 'VODUJPOBM1SPHSBNNJOH '1

Slide 3

Slide 3 text

ޒഒላӃ ೺ਞྻཫॴ༗తحᏐ ငҎ೭ޙฒܭࢉશ෦ݩૉ័࿨

Slide 4

Slide 4 text

ޒഒላӃ +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

Slide 5

Slide 5 text

ޒഒላӃ +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

Slide 6

Slide 6 text

ޒഒላӃ +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

Slide 7

Slide 7 text

ޒഒላӃ ॄኄੋ'1ʁ

Slide 8

Slide 8 text

ޒഒላӃ ఔࣜޠݴయൣ 1SPHSBNNJOH1BSBEJHNT

Slide 9

Slide 9 text

ޒഒላӃ ෺݅ಋ޲ఔࣜઃܭ 0CKFDU0SJFOUFE1SPHSBNNJOH

Slide 10

Slide 10 text

ޒഒላӃ ෧᧋៺ঝ &ODBQTVMBUJPO*OIFSJUBODF

Slide 11

Slide 11 text

ޒഒላӃ വᏐࣜఔࣜઃܭ 'VODUJPOBM1SPHSBNNJOH

Slide 12

Slide 12 text

ޒഒላӃ വᏐ 'VODUJPO

Slide 13

Slide 13 text

ޒഒላӃ ॄኄੋവᏐʁ

Slide 14

Slide 14 text

ޒഒላӃ f(x) = 3x + 2

Slide 15

Slide 15 text

ޒഒላӃ വᏐ༌ೖ值ᢛ༌ग़值೭ؒత᮫܎

Slide 16

Slide 16 text

ޒഒላӃ ७വᏐ 1VSF'VODUJPO

Slide 17

Slide 17 text

ޒഒላӃ 1VSF'VODUJPO ༌ग़݁Ռ୞᪑༌ೖ值༗᮫

Slide 18

Slide 18 text

ޒഒላӃ +4 # 不純 def one_weeks_later Time.now + 7.days end

Slide 19

Slide 19 text

ޒഒላӃ +4 # 比較純 def one_weeks_later(current_time) current_time + 7.days end

Slide 20

Slide 20 text

ޒഒላӃ 1VSF'VODUJPO ෆ။଄੒㐫ଶվᏓ

Slide 21

Slide 21 text

ޒഒላӃ ᔒ༗෭࡞༻ /PTJEFFGGFDU

Slide 22

Slide 22 text

ޒഒላӃ +4 # 不純 def add_book Book.create(title: '為你⾃⼰學 Ruby') end

Slide 23

Slide 23 text

ޒഒላӃ +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 # ???

Slide 24

Slide 24 text

ޒഒላӃ +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 # ???

Slide 25

Slide 25 text

ޒഒላӃ ෆՄᏓੑ *NNVUBCJMJUZ

Slide 26

Slide 26 text

ޒഒላӃ +4 // JavaScript const list = [1, 2, 3] const otherList = list console.log(list) // [1, 2, 3] otherList[0] = "a" console.log(list) // ???

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

ޒഒላӃ '1JO3VCZ

Slide 30

Slide 30 text

ޒഒላӃ +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]

Slide 31

Slide 31 text

ޒഒላӃ 3VCZฒෆࢉੋਅਖ਼త'1-BOHVBHF

Slide 32

Slide 32 text

ޒഒላӃ വᏐੋҰ౳ެຽ 'JSTU$MBTT$JUJ[FO

Slide 33

Slide 33 text

ޒഒላӃ +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

Slide 34

Slide 34 text

ޒഒላӃ 3VCZॴ༗త౦੢౎ੋ෺݅ &WFSZUIJOHJO3VCZJTBOPCKFDU

Slide 35

Slide 35 text

ޒഒላӃ ୠଖመ༗ࠣ౦੢ฒෆੋ෺݅

Slide 36

Slide 36 text

ޒഒላӃ ᩋํ๏ʮ෺݅Խʯ

Slide 37

Slide 37 text

ޒഒላӃ +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

Slide 38

Slide 38 text

ޒഒላӃ ෆՄᏓੑ *NNVUBCJMJUZ

Slide 39

Slide 39 text

ޒഒላӃ +4 # Data.define 是 Ruby 3.2 之後才加進來的新功能 Location = Data.define(:x, :y) point = Location.new(0, 0) puts point.x, point.y point.x = 100 # 錯誤

Slide 40

Slide 40 text

ޒഒላӃ ိᴍෳᯑత

Slide 41

Slide 41 text

ޒഒላӃ ᐬཬԽ $VSSZJOH

Slide 42

Slide 42 text

ޒഒላӃ ೺ݪຊधཁଟݸჩᏐతവᏐ ᫚׵੒Ұܥྻ୞ཁݸჩᏐతവᏐతաఔ

Slide 43

Slide 43 text

ޒഒላӃ +4 def add_numbers(a, b, c) a + b + c end # 柯⾥化 curried_add = -> (x) { -> (y) { -> (z) { add_numbers(x, y, z) } } }

Slide 44

Slide 44 text

ޒഒላӃ +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)

Slide 45

Slide 45 text

ޒഒላӃ +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

Slide 46

Slide 46 text

ޒഒላӃ ภവᏐ 1BSUJBM'VODUJPOT

Slide 47

Slide 47 text

ޒഒላӃ ෦份BQQMZݪ࢝വᏐɼઌݻఆവᏐత෦෼ ჩᏐɼճၚ઀डႫᰨჩᏐత৽വᏐ

Slide 48

Slide 48 text

ޒഒላӃ +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

Slide 49

Slide 49 text

ޒഒላӃ +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

Slide 50

Slide 50 text

ޒഒላӃ +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

Slide 51

Slide 51 text

ޒഒላӃ വᏐ߹੒ 'VODUJPO$PNQPTJUJPO

Slide 52

Slide 52 text

ޒഒላӃ ઌՃɼ࠶Ճഒɼ࠷ޙ࠶ฏํʂ

Slide 53

Slide 53 text

ޒഒላӃ +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

Slide 54

Slide 54 text

ޒഒላӃ ؅ઢ 1JQF

Slide 55

Slide 55 text

ޒഒላӃ +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

Slide 56

Slide 56 text

ޒഒላӃ 3VCZᔒ༗Ṝኄํศత౦੢

Slide 57

Slide 57 text

ޒഒላӃ +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

Slide 58

Slide 58 text

ޒഒላӃ +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

Slide 59

Slide 59 text

ޒഒላӃ ޻঎෰຿