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
260
Functional Ruby
高見龍
June 27, 2023
Tweet
Share
More Decks by 高見龍
See All by 高見龍
Generative AI 年會小聚 - AI 教我寫程式
eddie
0
17
讓數據說話:用 Python、Prometheus 和 Grafana 講故事
eddie
0
400
AI 時代的程式語言學習法
eddie
0
59
前端模組解放運動 - importmap
eddie
0
1.2k
Git 和 DevOps - 在混亂的流星群開發流程中找到小確幸
eddie
1
1.1k
模組化前端開發:從亂七八糟到組織有序
eddie
0
1.5k
被 Vue 框架耽誤的建置工具
eddie
2
950
開開心心寫測試,你的程式碼也會微笑
eddie
1
1.2k
閱讀原始碼 - 再戰十年的 jQuery
eddie
1
770
Other Decks in Technology
See All in Technology
OCI 運用監視サービス 概要
oracle4engineer
PRO
0
4.8k
日経電子版のStoreKit2フルリニューアル
shimastripe
1
140
Can We Measure Developer Productivity?
ewolff
1
150
DynamoDB でスロットリングが発生したとき_大盛りver/when_throttling_occurs_in_dynamodb_long
emiki
1
430
AWS Lambdaと歩んだ“サーバーレス”と今後 #lambda_10years
yoshidashingo
1
180
TypeScript、上達の瞬間
sadnessojisan
46
13k
OCI Security サービス 概要
oracle4engineer
PRO
0
6.5k
New Relicを活用したSREの最初のステップ / NRUG OKINAWA VOL.3
isaoshimizu
3
630
開発生産性を上げながらビジネスも30倍成長させてきたチームの姿
kamina_zzz
2
1.7k
生成AIが変えるデータ分析の全体像
ishikawa_satoru
0
170
10XにおけるData Contractの導入について: Data Contract事例共有会
10xinc
6
660
障害対応指揮の意思決定と情報共有における価値観 / Waroom Meetup #2
arthur1
5
480
Featured
See All Featured
Six Lessons from altMBA
skipperchong
27
3.5k
Optimizing for Happiness
mojombo
376
70k
How STYLIGHT went responsive
nonsquared
95
5.2k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
Fireside Chat
paigeccino
34
3k
A Modern Web Designer's Workflow
chriscoyier
693
190k
What's new in Ruby 2.0
geeforr
343
31k
Done Done
chrislema
181
16k
Producing Creativity
orderedlist
PRO
341
39k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
31
2.7k
Speed Design
sergeychernyshev
25
620
How GitHub (no longer) Works
holman
310
140k
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
ޒഒላӃ