Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Functional Ruby
Search
高見龍
June 27, 2023
Technology
1
310
Functional Ruby
高見龍
June 27, 2023
Tweet
Share
More Decks by 高見龍
See All by 高見龍
為你自己學 Python
eddie
0
610
Generative AI 年會小聚 - AI 教我寫程式
eddie
0
92
讓數據說話:用 Python、Prometheus 和 Grafana 講故事
eddie
0
620
AI 時代的程式語言學習法
eddie
0
130
前端模組解放運動 - importmap
eddie
0
1.4k
Git 和 DevOps - 在混亂的流星群開發流程中找到小確幸
eddie
1
1.2k
模組化前端開發:從亂七八糟到組織有序
eddie
0
1.6k
被 Vue 框架耽誤的建置工具
eddie
2
1k
開開心心寫測試,你的程式碼也會微笑
eddie
1
1.3k
Other Decks in Technology
See All in Technology
監視のこれまでとこれから/sakura monitoring seminar 2025
fujiwara3
10
2.5k
AWS全冠したので振りかえってみる
tajimon
0
150
AWS CDK 実践的アプローチ N選 / aws-cdk-practical-approaches
gotok365
4
180
工具人的一生: 開發很多 AI 工具讓我 慵懶過一生
line_developers_tw
PRO
0
970
_第3回__AIxIoTビジネス共創ラボ紹介資料_20250617.pdf
iotcomjpadmin
0
140
原則から考える保守しやすいComposable関数設計
moriatsushi
3
490
Uniadex__公開版_20250617-AIxIoTビジネス共創ラボ_ツナガルチカラ_.pdf
iotcomjpadmin
0
130
新卒3年目の後悔〜機械学習モデルジョブの運用を頑張った話〜
kameitomohiro
0
350
vLLM meetup Tokyo
jpishikawa
1
260
CIでのgolangci-lintの実行を約90%削減した話
kazukihayase
0
330
Navigation3でViewModelにデータを渡す方法
mikanichinose
0
190
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
52
31k
Featured
See All Featured
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Scaling GitHub
holman
459
140k
Producing Creativity
orderedlist
PRO
346
40k
Facilitating Awesome Meetings
lara
54
6.4k
Why Our Code Smells
bkeepers
PRO
337
57k
What's in a price? How to price your products and services
michaelherold
245
12k
The Cult of Friendly URLs
andyhume
79
6.4k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
137
34k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
6
690
Balancing Empowerment & Direction
lara
1
330
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Transcript
為你⾃⼰學 系列單元 ޒഒላӃ Functional Ruby
ޒഒላӃ വᏐࣜఔࣜઃܭ 'VODUJPOBM1SPHSBNNJOH '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
ޒഒላӃ +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
ޒഒላӃ +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
ޒഒላӃ ॄኄੋ'1ʁ
ޒഒላӃ ఔࣜޠݴయൣ 1SPHSBNNJOH1BSBEJHNT
ޒഒላӃ ݅ಋఔࣜઃܭ 0CKFDU0SJFOUFE1SPHSBNNJOH
ޒഒላӃ ෧ ঝ &ODBQTVMBUJPO*OIFSJUBODF
ޒഒላӃ വᏐࣜఔࣜઃܭ 'VODUJPOBM1SPHSBNNJOH
ޒഒላӃ വᏐ 'VODUJPO
ޒഒላӃ ॄኄੋവᏐʁ
ޒഒላӃ f(x) = 3x + 2
ޒഒላӃ വᏐ༌ೖ值ᢛ༌ग़值೭ؒత᮫
ޒഒላӃ ७വᏐ 1VSF'VODUJPO
ޒഒላӃ 1VSF'VODUJPO ༌ग़݁Ռ᪑༌ೖ值༗᮫
ޒഒላӃ +4 # 不純 def one_weeks_later Time.now + 7.days end
ޒഒላӃ +4 # 比較純 def one_weeks_later(current_time) current_time + 7.days end
ޒഒላӃ 1VSF'VODUJPO ෆ။㐫ଶվᏓ
ޒഒላӃ ᔒ༗෭࡞༻ /PTJEFFGGFDU
ޒഒላӃ +4 # 不純 def add_book Book.create(title: '為你⾃⼰學 Ruby') end
ޒഒላӃ +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 # ???
ޒഒላӃ +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 # ???
ޒഒላӃ ෆՄᏓੑ *NNVUBCJMJUZ
ޒഒላӃ +4 // JavaScript const list = [1, 2, 3]
const otherList = list console.log(list) // [1, 2, 3] otherList[0] = "a" console.log(list) // ???
ޒഒላӃ +4 // Rust fn main() { let list =
[1, 2, 3]; list[0] = 100; // 預設是不能修改的 println!("{:?}", list); }
ޒഒላӃ +4 # Elixir list = [1, 2, 3] list[0]
= 100 # 預設是不可修改的
ޒഒላӃ '1JO3VCZ
ޒഒላӃ +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]
ޒഒላӃ 3VCZฒෆࢉੋਅਖ਼త'1-BOHVBHF
ޒഒላӃ വᏐੋҰެຽ 'JSTU$MBTT$JUJ[FO
ޒഒላӃ +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
ޒഒላӃ 3VCZॴ༗త౦ੋ݅ &WFSZUIJOHJO3VCZJTBOPCKFDU
ޒഒላӃ ୠଖመ༗ࠣ౦ฒෆੋ݅
ޒഒላӃ ᩋํ๏ʮ݅Խʯ
ޒഒላӃ +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
ޒഒላӃ ෆՄᏓੑ *NNVUBCJMJUZ
ޒഒላӃ +4 # Data.define 是 Ruby 3.2 之後才加進來的新功能 Location =
Data.define(:x, :y) point = Location.new(0, 0) puts point.x, point.y point.x = 100 # 錯誤
ޒഒላӃ ိᴍෳᯑత
ޒഒላӃ ᐬཬԽ $VSSZJOH
ޒഒላӃ ݪຊधཁଟݸჩᏐతവᏐ ҰܥྻཁݸჩᏐతവᏐతաఔ
ޒഒላӃ +4 def add_numbers(a, b, c) a + b +
c end # 柯⾥化 curried_add = -> (x) { -> (y) { -> (z) { add_numbers(x, y, z) } } }
ޒഒላӃ +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)
ޒഒላӃ +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
ޒഒላӃ ภവᏐ 1BSUJBM'VODUJPOT
ޒഒላӃ ෦份BQQMZݪ࢝വᏐɼઌݻఆവᏐత෦ ჩᏐɼճၚडႫᰨჩᏐత৽വᏐ
ޒഒላӃ +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
ޒഒላӃ +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
ޒഒላӃ +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
ޒഒላӃ വᏐ߹ 'VODUJPO$PNQPTJUJPO
ޒഒላӃ ઌՃɼ࠶Ճഒɼ࠷ޙ࠶ฏํʂ
ޒഒላӃ +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
ޒഒላӃ ઢ 1JQF
ޒഒላӃ +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
ޒഒላӃ 3VCZᔒ༗Ṝኄํศత౦
ޒഒላӃ +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
ޒഒላӃ +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
ޒഒላӃ