C# can be functional pt1: The Maybe Monad

record๋ฅผ ์จ๋ณด๊ธฐ ์œ„ํ•ด ๋ชจ๋‚˜๋“œ๊นŒ์ง€ ๊ฐ”์Šต๋‹ˆ๋‹ค.
์šฐ์ฃผ์˜ ๋น„๋ฐ€ ๋ชจ๋‚˜๋“œ์— ์ ‘๊ทผํ•ด๋ด…์‹œ๋‹ค

๋ชจ๋‚˜๋“œ์˜ ์„ธ๊ณ„๋ฅผ ํƒ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด Monad๋ผ๋Š” ์ฝ˜์†” ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์‚ฌ์‹ค ๋ชจ๋‚˜๋“œ ๋ฐ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๊ณผ๊ฑฐ์— ์‹œ๊ฐ„์„ ์ผ์ง€๋งŒ ์ œ๊ฒƒ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค. C#9 record๋ฅผ ์ด์šฉํ•ด ๋ชจ๋‚˜๋“œ์˜ ์„ธ๊ณ„์— ๋น ์ง€๊ธฐ ์œ„ํ•ด, ๋‹ค์‹œ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

C# 9์˜ ๋ชจ๋‚˜๋“œ ์„ธ๊ณ„์—๋Š” ๋”์ด์ƒ Main() ๋ฉ”์†Œ๋“œ ์—†๋Š”(์žˆ์ง€๋งŒ ๊ฐ์ถฐ์ง„) ์„ธ๊ณ„์ž…๋‹ˆ๋‹ค.

using System;

Console.WriteLine("Hello! Monad!");

์œ„์— ๊ณต์œ ๋œ ์•„ํ‹ฐํด์„ ์ด์šฉํ•ด ๋น ๋ฅด๊ฒŒ ๋ชจ๋‚˜๋“œ ์„ธ๊ณ„๋ฅผ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.

์ด ์„ธ์ƒ์˜ ์ตœ์†Œ ์›์†Œ๋Š” Maybe์ž…๋‹ˆ๋‹ค. Maybe๋Š” ์•„๋ฌด๊ฒƒ๋„ ์—†๋Š” Nothing๊ณผ ์ด์™ธ์˜ ๋ชจ๋“ ๊ฒƒ ์ค‘์˜ ๋ถ„๋ช…ํ•จ์ธ Just๋กœ ์ด๋ฃจ์–ด์ง„ ์„ธ์ƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ชจ๋‚˜๋“œ ์„ธ์ƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋น ๋ฅด๊ฒŒ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

using System;

;

abstract record Maybe<T>;
record Nothing<T> : Maybe<T>;
record Just<T>(T Value) : Maybe<T>;

์ด๋Ÿฐ ์„ธ์ƒ์€ C# 9์˜ ์ตœ์ƒ์œ„ ๋ฌธ์— ์˜ํ•ด์„œ ์•„๋ฌด๊ฒƒ๋„ ์—†๋Š” ๋นˆ ๊ณต๊ฐ„์ธ ์„ธ๋ฏธ์ฝœ๋ก (;)์œผ๋กœ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ์„ธ์ƒ์€ ์ตœ์†Œ ์›์ž์˜ ์ •์˜๋งŒ ์žˆ์„ ๋ฟ ์—ฌ์ „ํžˆ ์•„๋ฌด๊ฒƒ๋„( ; ) ์—†๋Š” ๋นˆ ์„ธ์ƒ์ž…๋‹ˆ๋‹ค.

๊ทธ์ „์— ๋ชจ๋‚˜๋“œ ์„ธ๊ณ„์—์„œ๋Š” nullableํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ null๊ฐ’์— ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฒฝ๊ณ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋„๋ก ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ”„๋กœ์ ํŠธ์— ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

image

์ด ์†์„ฑ์„ ์ฃผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด null์ผ ๊ฒฝ์šฐ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์ค๋‹ˆ๋‹ค.

image