F# ๋ฐฐ์šฐ๊ธฐ - slog

๋˜ ์–ธ์ œ ๋๋‚ ์ง€ ๋ชจ๋ฅผ ์—ฌ์ •์„ ๊ฑธ์–ด๋ด…๋‹ˆ๋‹ค.

F# ๋ฐฐ์šฐ๊ธฐ ์ž…๋‹ˆ๋‹ค.

F#์ด ์–ด๋–ค ์–ธ์–ด์ธ๊ฐ€ ํ™•์ธ์€ ์œ„ํ‚ค๋ฐฑ๊ณผ๋ฅผ ์ฐธ๊ณ  ํ•ฉ์‹œ๋‹ค.

2005๋…„์— ๋ฐœํ‘œํ•œ ์–ธ์–ด๊ตฐ์š”. ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋กœ๋งŒ ์•Œ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ๋‹ค์ค‘ ํŒจ๋Ÿฌ๋‹ค์ž„ ์–ธ์–ด๋กœ ๋ถ„๋ฅ˜ ๋˜๋Š”๊ตฐ์š”.

๋Œ€ํ‘œ ํ™ˆํŽ˜์ด์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

https://fsharp.org/

6๊ฐœ์˜ ์ข‹์•„์š”

F#์œผ๋กœ Blazor๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์•ˆํƒ€๊น๊ฒŒ๋„ ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ ์ค‘ F#์„ ์ง€์›ํ•˜์ง€๋Š” ์•Š๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

๊ด€๋ จํ•ด์„œ Bolero ํ”„๋กœ์ ํŠธ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

F#์œผ๋กœ SPA๋ฅผ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•œ๋‹ค.

https://fsbolero.io/

2๊ฐœ์˜ ์ข‹์•„์š”

๊ฐœ๋ฐœ ํ™˜๊ฒฝ

๊ฐœ๋ฐœ ํ™˜๊ฒฝ์€ ์•„๋ž˜ ๋ฌธ์„œ(์œˆ๋„์šฐ ํ™˜๊ฒฝ)๋ฅผ ์ฐธ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

https://fsharp.org/use/windows/

๋‚˜๋Š” Visual Studio Code + Ionide ํ™˜๊ฒฝ์œผ๋กœ ๊ตฌ์ถ• ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

https://ionide.io/

2๊ฐœ์˜ ์ข‹์•„์š”

๊ฐœ๋ฐœ ํ™˜๊ฒฝ #2

์ด์œ ๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์ด๋ฏธ Ionide for F# ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์„ค์น˜๋˜์–ด ์žˆ๋‹ค. C# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ Visual Studio Code์— ๊ตฌ์„ฑํ•˜๋ฉด F#๋„ ๋”ฐ๋ผ์„œ ๊ตฌ์„ฑ๋˜๋Š” ๊ฒƒ์ธ๊ฐ€? ์ดํ›„ ์ •ํ™•ํžˆ ์‚ดํŽด๋ณผ ํ•„์š”๊ฐ€ ์žˆ๊ฒ ๋‹ค.

์œ„์˜ ๊ธ€์„ ํ†ตํ•ด ๊ทธ๋Œ€๋กœ ๋”ฐ๋ผ ํ•ด๋ณธ๋‹ค.

๊ฐœ๋ฐœ ํ™˜๊ฒฝ #3

๊ฐ€์ƒ ํ™˜๊ฒฝ์—์„œ ๋‹ค์Œ์ฒ˜๋Ÿผ ๊ตฌ์„ฑํ•˜์˜€๋‹ค.

dotnet new console -lang "F#" -o HelloWorldFSharp
cd HelloWorldFSharp
code .

launch.json์€ ๋‹ค์Œ์ฒ˜๋Ÿผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

{
    "configurations": [

        {
            "type": "coreclr",
            "request": "launch",
            "name": "Launch HelloWorldFSharp",
            "program": "${workspaceFolder}/bin/Debug/net8.0/HelloWorldFSharp.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "stopAtEntry": false,
            "console": "internalConsole"
        }
    ]
}

Start Debugging์œผ๋กœ breakpoint๊ฐ€ ์ž˜ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

F#์˜ Visual Studio Code ๊ตฌ์„ฑ์ด ์›ํ™œํ•˜์ง€ ์•Š์•„ (๊ด€๋ จํ•ด์„œ Visual Studio Code๋กœ F#์„ ์ฝ”๋”ฉํ•˜์‹œ๋Š” ๋ถ„๊ป˜๋Š” ํ™˜๊ฒฝ ๊ตฌ์„ฑ์„ ์–ด๋–ป๊ฒŒ ํ–ˆ๋Š”์ง€ ๋Œ“๊ธ€๋กœ ๋„์›€ ๋ฐ”๋ž„๊ป˜์š”) Visual Studio ํ™˜๊ฒฝ์—์„œ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

F# ๊ด€๋ จ ๊ตญ๋‚ด ๊ธ€

์ด๋ฏธ 5๋…„ ์ „์˜ ๊ธ€์ด๊ธด ํ•˜์ง€๋งŒ ๋‚ด์šฉ์ด ์ข‹์•„ ๊ณต์œ  ํ•ฉ๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

F#์œผ๋กœ ๋งŒ๋“  ๊ตญ๋‚ด ํ”„๋กœ์ ํŠธ

https://csrc.kaist.ac.kr/blog/2020/08/12/๋ฐ”์ด๋„ˆ๋ฆฌ-๋ถ„์„์—-์›ฌ-fsharp/

https://kwangkeunyi.snu.ac.kr/~kwang/paper/maso/1.html

B2R2๋Š” F#์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ์ด์ง„ ๋ถ„์„์„ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜, ํ•จ์ˆ˜ ๋ฐ ๋„๊ตฌ ๋ชจ์Œ โ€“ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž…๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

์ ‘๊ทผ ๋ฌธ์„œ

https://fsprojects.github.io/fsharp-cheatsheet/

ํŠนํžˆ Cheat Sheet์˜ ๊ฒฝ์šฐ ๋‚˜๊ฐ™์€ ์ดˆ๋ณด์ž์—๊ฒŒ๋Š” F#์„ ํŒŒ์•…ํ•˜๊ธฐ์— ์œ ์šฉํ•œ ๋ฌธ์„œ์ผ ๊ฒƒ ๊ฐ™๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

Fable - F#์„ ์ด์šฉํ•ด์„œ JavaScript ๋“ฑ์˜ ์–ธ์–ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ.

์ œ๊ฐ€ ์ „์— ํ•œ๋ฒˆ ์†Œ๊ฐœํ–ˆ์—ˆ๊ตฐ์š”.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— REPL๋„ ์›น ํŽ˜์ด์ง€๋กœ ๋ผ์ด๋ธŒ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://fable.io/repl/

1๊ฐœ์˜ ์ข‹์•„์š”

F#์„ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ์ด์œ 

๋ฌผ๋ก  ์ข‹๋‹ค๊ณ  ๋‹ค์ˆ˜(์˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ)๊ฐ€ ์‚ฌ์šฉ ํ•  ๋ฌด์—‡์ด ๋œ๋‹ค๋Š” ๊ฒƒ์€ ์•„๋‹๊บผ์—์š”. ์–ด์จŒ๋“  ์ด ๊ธ€์„ ํ†ตํ•ด F#์˜ ์žฅ์ ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

C# ๊ฐœ๋ฐœ์ž๊ฐ€ F#์„ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ์ด์œ 

๋ผ๋Š” ์ œ๋ชฉ์œผ๋กœ ํ•™์Šต ๋ชฉ์  ๋ฐ ์ปจํ…์ธ  ์ƒ์„ฑ ๋ชฉํ‘œ๋ฅผ ์„ค์ •ํ•ด์•ผ๊ฒ ๋‹ค. ์šฐ๋ฆฌ๋‚˜๋ผ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋˜๋ ค๋Š” ์ผ๋ฐ˜ ํ•™์ƒ์ด F#์„ ๋ฐฐ์šฐ๋ ค ํ•  ๊ฐ€๋Šฅ์„ฑ์€ 0% ์ˆ˜๋ ด. ์™œโ€ฆ F#๋Š” ์ปค๋…• Unity๋กœ ๊ฒŒ์ž„ ๊ฐœ๋ฐœํ•˜๋ ค๊ณ  ํ•˜๋Š” ์†Œ์ˆ˜์˜ ํ•™์ƒ ๋นผ๊ณ ๋Š” C#์„ ๋ฐฐ์šธ ์ƒ๊ฐ๋„, ์˜์ง€๋„ ์—†๊ณ  ์žˆ๋Š”์ง€์กฐ์ฐจ ๋ชจ๋ฅธ๋‹ค. F#์œผ๋กœ ์ทจ์—…ํ•˜๊ธฐ๋Š” ํ•˜๋Š˜์— ๋ณ„ ๋”ฐ๊ธฐ์ผ ์ˆ˜ ์žˆ๋‹ค. F#์€ ์•„๋งˆ๋„ ๋ณธ์ธ ์—ฐ๊ตฌ์— ํ™œ์šฉํ•  ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„ ๊ทน์†Œ์ˆ˜์˜ ํ•™/์„์‚ฌ์˜ ํ•™์ƒ๋“ค์ด ์ ‘ํ•˜๊ณ ์ž ํ•˜๋Š” ์–ธ์–ด์ผ ๊ฒƒ์ด๋‹ค.

์‹ค์ œ๋กœ ์ทจ์—…์€ ์‚ถ์—์„œ ์ค‘์š”ํ•œ ์ด๋ฒคํŠธ์ด๋‹ค

ํ•จ์ˆ˜ํ˜• ์–ธ์–ด ๋ฐ F#์— ๋Œ€ํ•ด ํฅ๋ฏธ์™€ ๊ฐ์„ ์กฐ๊ธˆ์”ฉ ์žก๊ฒŒ ๋„์šด ์‚ฌ์ดํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ์ปจํ…์ธ ๊ฐ€ 2015๋…„ ์ด์ „์˜ ๊ธ€๋“ค์ด๋ผ ์ชผ๊ธˆ ์•„์‰ฝ๊ธฐ๋Š” ํ•˜์ง€๋งŒ ํ•™์Šต ํ›„ F#์ด ์–ด๋–ป๊ฒŒ ๋ณ€ํ™”๋˜์—ˆ๋Š”์ง€๋ฅผ ์‚ดํŽด๋ด์•ผ๊ณ˜๋‹ค. ๊ทธ๊ฒƒ ๋นผ๊ณ ๋Š” ํ›Œ๋ฅญํ•œ ๋‚ด์šฉ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด

The 'Why use F#' series | F# for fun and profit

์ด ๊ธ€์„ ์ญ‰ ์‚ดํŽด๋ณด๋ฉด F#์— ๋Œ€ํ•ด ๊ฐ์„ ์žก์„ ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ธ€ ์™ธ์—๋„ ํ›Œ๋ฅญํ•œ ๊ธ€๋“ค์ด ๋งŽ๋‹ค.

3๊ฐœ์˜ ์ข‹์•„์š”

F# ๋ฐฐ์šฐ๊ธฐ (feat. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ)

๋ช…๋ นํ˜• ๊ฐœ๋…์„ ๊ฐ€์ง€๊ณ  ์ ‘๊ทผํ•˜์ง€ ๋ง์ž

๋ช…๋ นํ˜• ๊ฐœ๋…์ด๋ž€ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ์ ‘ํ–ˆ๋˜ C/C++/Java/JavaScript/โ€ฆC#! ์–ธ์–ด๋“ค์ด ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๊ฐ€ ๊ณง ์‹คํ–‰๋˜์–ด ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฐœ๋…์„ ๋งํ•œ๋‹ค. ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋Š” ๋ณ€์ˆ˜(๋ณ€ํ•˜๋Š” ์ €์žฅ์†Œ)๋„ ์—†๊ณ , ๋ฃจํ”„(๋ฐ˜๋ณต๋ฌธ)๋„ ์—†๊ณ , ๊ฐ์ฒด๋„ ์—†๋‹ค.

๋ฌผ๋ก  F#์€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋Š” ์•„๋‹ˆ๋‹ค. .NET ์ƒํƒœ๊ณ„๋ฅผ ํ™œ์šฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๊ฐ์ฒด์ง€ํ–ฅ ์šฉ๋ฒ•๋„ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š๊ณ (๋ถˆ๋ณ€), ๋ฃจํ”„๋„ ์—†๊ณ (์žฌ๊ท€), ๊ฐ์ฒด๋„ ์—†๊ณ (ํ•จ์ˆ˜) ์–ด๋–ป๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ’€ ์ˆ˜ ์žˆ์„๊นŒ?

์†”์งํžˆ ๋‚˜๋„ ์•„์ง๊นŒ์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค. ๋ฐฐ์šฐ๊ณ  ์žˆ๋Š” ์ค‘์ด๋‹ค.
๋ญ ์ถ”์ธก์œผ๋กœ๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜•์„ ์ง€ํ–ฅํ•˜๋ฉฐ ์˜ˆ์ธก๋˜๋Š”(๋ถˆ๋ณ€) ํ•จ์ˆ˜์˜ ์กฐ๋ฆฝ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ‘ธ๋Š” ๊ฒƒ์ด๋ฆฌ๋ผ

๋ช…๋ นํ˜•๊ณผ ๋ฐ˜๋Œ€๋˜๋Š” ๊ฐœ๋…์€ ์„ ์–ธํ˜•์ด๋‹ค. ๋‹ค์Œ์˜ ๊ธ€์„ ์‚ดํŽด๋ณด์ž.

https://velog.io/@phs880623/ํ•จ์ˆ˜ํ˜•-ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๊ทธ๋ ‡๋‹ค๊ณ  ํ•œ๋‹ค. ํ›Œ๋ฃฝํ•˜๊ฒŒ ์ •๋ฆฌํ•˜์…จ๋Š”๋ฐ ์กฐ๊ธˆ ๋” ๊ธ€์ด ์งง์•„๋„ ๋ ๋ป”ํ–ˆ๋‹ค.

์ƒ๊ฐํ•˜๋Š” ๋ฐฉ์‹์„ ๋ฐ”๊พธ์ž

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ์ด์ „์˜ ์ ˆ์ฐจ์ง€ํ–ฅ(๋ช…๋ นํ˜•) ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ ๊ด€์ ์ด ํ•„์š”ํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋ฌธ์ œ ํ•ด๊ฒฐ์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ๋‹ค๋ฅด๋‹ค.

๋ช…๋ นํ˜•์ด ์•„๋‹Œ ํ•จ์ˆ˜ํ˜• ์Šคํƒ€์ผ๋กœ ์ฝ”๋”ฉํ•˜๋ ค๋ฉด ํ•จ์ˆ˜์  ์‚ฌ๊ณ ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์•„๋ž˜์˜ ์‹œ๋ฆฌ์ฆˆ๋ฅผ ์‚ดํŽด๋ณด์ž.

ํ•ด์•ผ ํ•  ์ผ๊ณผ ํ•˜์ง€ ๋ง์•„์•ผ ํ•  ์ผ

mutable์€ ์ดˆ๊ธฐ์—๋Š” ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž.

๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด๋ฅผ ์ ˆ์ฐจ์ง€ํ–ฅ ์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ F#์€ ๋น„ํ•จ์ˆ˜ํ˜• ์–ธ์–ด์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ’์ด mutable์ด ๋˜์ง€ ์•Š๋„๋ก ์ดˆ๊ธฐ์—๋Š” ์ง€์–‘ํ•˜์ž.

for๋‚˜ if-then-else๋ฅผ ์“ฐ์ง€ ๋ง์ž

์žฌ๊ท€์™€ ํŒจํ„ด ๋งค์นญ์„ ์“ฐ์ž.

"hello".length ๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  String.length "hello"๋ฅผ ๋Œ€์‹  ์“ฐ์ž

๊ฐœ์ฒด์˜ ์‚ฌ์šฉ์ด ์•„๋‹ˆ๋ฏ€๋กœ ๊ทธ๋ ‡๋‹ค๊ณ  ํ•œ๋‹ค. (์ •ํ™•ํ•œ ๊ฑด ์ข€ ๋” ํ•™์Šตํ•œ ๋’ค ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์œผ๋กœ)

ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์ง€ ๋ง์ž

์ด ๋ง์€ ์—ญ์œผ๋กœ F#์ด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์–ด์จŒ๋“  ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜•์„ ์ง€ํ–ฅ์—์„œ ํŠœํ”Œ, ๋ ˆ์ฝ”๋“œ, ์œ ๋‹ˆ์–ธ ๋“ฑ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ’€์–ด์•ผ ํ•œ๋‹ค.

๋””๋ฒ„๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž

F#์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ข€ ๋” ์—„๊ฒฉํ•˜๋ฏ€๋กœ (์ด๊ฒƒ๋„ ๋” ํ•™์Šตํ•œ ๋’ค ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์œผ๋กœ)

๋ฐ˜๋ฉด์—:

์ž‘์€ type ํŠนํžˆ union type์„ ๊ถŒ์žฅํ•จ

๊ฐ€๋ณ๊ณ  ์‰ฌ์šฐ๋ฉฐ, ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ์‰ฝ๊ฒŒ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์ •ํ™•์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค.

list๋ฐ seq์œ ํ˜•๊ณผ ๊ด€๋ จํ•ด์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋“ˆ์„ ์ˆ™๋‹ฌํ•จ

List.fold๋ฐ List.map๋“ฑ์˜ ํ•จ์ˆ˜๋Š” ๊ฐ•๋ ฅํ•˜๋‹ค. ์ดํ•ดํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ณณ์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ปฌ๋ ‰์…˜ ๋ชจ๋“ˆ์„ ์ดํ•ดํ–ˆ๋‹ค๋ฉด ์žฌ๊ท€๋ฅผ ํ”ผํ•ด์•ผ ํ•จ

๊ผฌ๋ฆฌ ์žฌ๊ท€์ธ์ง€ ํ™•์ธํ•ด์•ผ ํ•˜๋ฉฐ ๋Œ€๋ถ€๋ถ„ List.fold๋กœ ๋ฌธ์ œ๋ฅผ ํ’€ ์ˆ˜ ์žˆ์Œ

๊ฐ€๋Šฅํ•œ ํŒŒ์ดํ”„(|>)์™€ ์ปดํฌ์ง€์…˜(>>)์„ ํ™œ์šฉํ•จ

F#์€ f(g(x))๋ณด๋‹ค ๊น”๋”ํ•˜๊ฒŒ ํŒŒ์ดํ”„์™€ ์ปดํฌ์ง€ํ˜„์œผ๋กœ ํ‘œํ˜ˆํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ถ€๋ถ„ ์ ์šฉ์„ ์ดํ•ดํ•˜๊ณ  ์•”๋ฌต์  ์Šคํƒ€์ผ์— ์ต์ˆ™ํ•ด์ง€์ž

(โ€ฆ ๋ฌด์Šจ ๋ง์ธ์ง€ ๋ชจ๋ฅด๊ฒ ์Œ ์ดํ•ดํ•˜๊ณ  ์ˆ˜์ •ํ•  ๊ฒƒ)

๋Œ€ํ™”ํ˜• ์ฐฝ์„ ์ด์šฉํ•ด์„œ ์ฝ”๋“œ ์กฐ์ž‘์„ ํ…Œ์ŠคํŠธํ•˜์ž

2๊ฐœ์˜ ์ข‹์•„์š”

๋ถ€๋ถ„์ ์šฉ ์ „์— ์ปค๋ง์„ ๋จผ์ €โ€ฆ :melting_face:

์กฐ๊ธˆ ๋” ์˜๊ฒฌ ๋ถ€ํƒ๋“œ๋ฆด๊ป˜์š” ^^ ํŽธํ•˜๊ฒŒ ๋ง์”€ํ•ด์ฃผ์„ธ์š”~

1๊ฐœ์˜ ์ข‹์•„์š”

C#์— ๋น„ํ•ด F#์˜ ์ฃผ์š” ์ด์ 

  • ๊ฐ„๊ฒฐํ•จ : ์ค‘๊ด„ํ˜ธ, ์ปด๋งˆ, ์„ธ๋ฏธ์ฝœ๋ก  ๋“ฑ์˜ ๋…ธ์ด์ฆˆ?์™€ ์œ ํ˜• ์ถ”๋ก  ์‹œ์Šคํ…œ์œผ๋กœ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด ์ง
  • ํŽธ์˜์„ฑ : ๋ณต์žกํ•œ ์œ ํ˜•์„ ์‰ฝ๊ฒŒ ์ •์˜ํ•˜๊ณ  ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๊ฐ–๊ฑฐ๋‚˜ ๊ธฐ์กด ํ•จ์ˆ˜๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ
  • ์ •ํ™•์„ฑ : null ์ฐธ์กฐ ์˜ˆ์™ธ ๋“ฑ์˜ ์ผ๋ฐ˜์ ์ธ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ์œ ํ˜• ์‹œ์Šคํ…œ์ด ์žˆ์œผ๋ฏ€๋กœ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์œ ํ˜• ์˜ค๋ฅ˜๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์˜ค๋ฅ˜๋ฅผ ์žก์„ ์ˆ˜ ์žˆ์Œ
  • ๋™์‹œ์„ฑ : ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ ๋ถˆ๋ณ€์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์ž ๊ธˆ์„ ํ”ผํ•˜๋Š” ์ž์—ฐ์Šค๋Ÿฐ ๋™์‹œ์„ฑ์„ ์ง€์›ํ•จ. ๋™์‹œ์„ฑ ๊ด€๋ จ ๋‹ค์–‘ํ•œ ๋‚ด์žฅ ๋„๊ตฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ผ๋ฆฌ๊ฐ€ ์žˆ์Œ
  • ์™„์ „์„ฑ : F#์€ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด์ผ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์Šคํƒ€์ผ ๋˜ํ•œ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— C#์—์„œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ์Œ

โ€ฆ ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์•„์ง์€ ์ „๋ฐ˜์ ์ธ ์–ธ์–ด์˜ ํŠน์ง• ๋ฐ ์‚ฌ์šฉ๋ฒ•์„ ์ดํ•ดํ•œ ๋‹จ๊ณ„๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”์ ์œผ๋กœ ๊ธฐ๋กโ€ฆ

2๊ฐœ์˜ ์ข‹์•„์š”

F# ๋ฌธ๋ฒ• ์ตํžˆ๊ธฐ (60์ดˆ)

C#๊ณผ์˜ ์ค‘์š”ํ•œ ์ฐจ์ด์ 

  • ์ค‘๊ด„ํ˜ธ ๋Œ€์‹  ๋„์–ด์“ฐ๊ธฐ
  • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ์‰ผํ‘œ ๋Œ€์‹  ๊ณต๋ฐฑ ์‚ฌ์šฉ
  • ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ ์‚ฌ์šฉ ์ „์— ์ •์˜๋˜์–ด์•ผ ํ•จ
let myInt = 5
let myFloat = 3.14
let myString = "hello"

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถˆ๋ณ€์œผ๋กœ ์ •์˜ ๋ฉ๋‹ˆ๋‹ค.

let twoToFive = [2; 3; 4; 5]
let twoToFive2 = [
    2
    3
    4
    5
]
let twoToFive3 = [2..5]
let twoToFive4 = [for i in 2..5 -> i]


printfn "%A" twoToFive
printfn "%A" twoToFive2
printfn "%A" twoToFive3
printfn "%A" twoToFive4

๊ฒฐ๊ณผ๋Š”? ๋ชจ๋‘ [2; 3; 4; 5] ์ด๋‹ค.
(๋ฌผ๋ก  ์–ด๋–ค ๊ฒƒ์ด ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๊ฐ€ ์ปดํŒŒ์ผ ํƒ€์ž„์ธ์ง€ ๋Ÿฐํƒ€์ž„์ธ์ง€๋Š” ์•„์ง์€ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค.)

๊ทธ๋ฆฌ๊ณ โ€ฆ [1;2;3] ์ด๋Ÿฐ ํ‘œํ˜„์€ ์ผ๋ฐ˜์ ์ธ ์—ฐ์† ๋ฐฐ์—ด์ด ์•„๋‹ˆ๋ผ ๋งํฌ๋“œ๋ฆฌ์ŠคํŠธ์ด๋‹ค!
(๋ฌผ๋ก  ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฐ์† ๋ฐฐ์—ด๋“ค์˜ ์ง‘ํ•ฉ์ด ๋˜๋„๋ก ์ตœ์ ํ™” ๋˜๊ธด ํ•  ๊ฒƒ์ด๋‹ค. ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค)

์ผ๋ฐ˜ ์—ฐ์† ๋ฐฐ์—ด์€ [|1; 2; 3|] ๋ผ๊ณ  ์‚ฌ์šฉํ•œ๋‹ค.

let oneToFive = 1 :: twoToFive
printfn "%A" oneToFive

์•ž์— 1์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ชฉ๋ก์„ ์ƒ์„ฑํ•œ๋‹ค. ์ƒˆ๋กœ ์ƒ์„ฑํ•œ ๋ชฉ๋ก์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ณต์‚ฌ๊ฐ€ ์•„๋‹ˆ๋ผ ๋งํฌ๋“œ๋ฆฌ์ŠคํŠธ๋กœ ์ฐธ์กฐํ•˜์—ฌ ๋น ๋ฅด๊ฒŒ ์ƒ์„ฑํ•œ๋‹ค.

let zeroToFive = [0;1] @ twoToFive

๋‘ ๋ชฉ๋ก์„ ์—ฐ๊ฒฐํ•ด์„œ ์ƒˆ๋กœ์šด ๋ชฉ๋ก์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.

let square x = x * x
square 3

let add x y = x + y
add 2 3

ํ•จ์ˆ˜๋ฅผ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

let evens list =
    let isEven x = x%2 = 0
    List.filter isEven list

evens oneToFive

ํ•จ์ˆ˜ ์•ˆ์— ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ค„์ด๊ฑฐ๋‚˜ ๊ฐ€๋…์„ฑ์„ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

let sumOfSquaresTo100 =
    List.sum ( List.map square [1..100] )

์ด๋ ‡๊ฒŒ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ ํŒŒ์ดํ”„๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข€ ๋” ์ž์—ฐ์Šค๋Ÿฝ๋‹ค.

let sumOfSquaresTo100piped =
   [1..100] |> List.map square |> List.sum

square ํ•จ์ˆ˜ ๋Œ€์‹  ๋žŒ๋‹ค ํ•จ์ˆ˜๋กœ ๋ฐ”๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

let sumOfSquaresTo100withFun =
   [1..100] |> List.map (fun x->x*x) |> List.sum

ํŒจํ„ด ๋งค์นญ์€ ์›๋ž˜ F#์—์„œ ์ œ๊ณต๋˜๋˜ ๊ฒƒ์ด๋‹ค.

let simplePatternMatch =
   let x = "a"
   match x with
    | "a" -> printfn "x is a"
    | "b" -> printfn "x is b"
    | _ -> printfn "x is something else"

F#์—์„œ๋Š” Option ํƒ€์ž…์— ์˜ํ•ด ๊ฐ’์ด ์žˆ์„์ˆ˜๋„ ์žˆ๊ณ  ์—†์„ ์ˆ˜๋„ ์žˆ๋Š” ์ƒํƒœ๋ฅผ ์ข€ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

let validValue = Some(99)
let invalidValue = None

Option์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒจํ„ด ๋งค์นญ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

let optionPatternMatch input =
   match input with
    | Some i -> printfn "input is an int=%d" i
    | None -> printfn "input is missing"

optionPatternMatch validValue
optionPatternMatch invalidValue

ํŠœํ”Œ์€ ์ปด๋งˆ๋กœ ํ‘œํ˜„ํ•œ๋‹ค.

let twoTuple = 1,2
let threeTuple = "a",2,true

๋ ˆ์ฝ”๋“œ ์œ ํ˜•์€ ์ด๋ฆ„ ํ•„๋“œ๋กœ ์„ธ๋ฏธ์ฝœ๋ก ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ํ‘œํ˜„ํ•œ๋‹ค.

type Person = {First:string; Last:string}
let person1 = {First="john"; Last="Doe"}

C#์—์„œ ๊ทธ๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์œ ๋‹ˆ์˜จ ์œ ํ˜•์ด๋‹ค.

type Temp =
  | DegreesC of float
  | DegreesF of float
let temp = DegreesF 98.6

Temp ์œ ํ˜•์€ DegreesC์ผ ์ˆ˜๋„ ์žˆ๊ณ  DegreesF์ผ ์ˆ˜๋„ ์žˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์œ ํ˜•์€ ์žฌ๊ท€์ ์œผ๋กœ ์ •์˜๋  ์ˆ˜ ๋„ ์žˆ๋‹ค.

type Employee =
  | Worker of Person
  | Manager of Employee list
let jdoe = {First="John";Last="Doe"}
let worker = Worker jdoe

์ถœ๋ ฅ์€ %A์„ ์ค˜์„œ ๊ฐ’์„ ์ด์˜๊ฒŒ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.

printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
printfn "A string %s, and something generic %A" "hello" [1;2;3;4]

printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
         twoTuple person1 temp worker
5๊ฐœ์˜ ์ข‹์•„์š”

F#๊ณผ C# ๋น„๊ต : ๊ฐ„๋‹จํ•œ ํ•ฉ๊ณ„

C# ๊ฐœ๋ฐœ์ž๊ฐ€ F#์˜ ๊ฐ„๋‹จ ๋ช…๋ฃŒํ•œ ์ฝ”๋“œ์˜ ๋งค๋ ฅ์„ ๋А๋‚„ ์ˆ˜ ์žˆ๋„๋ก ๊ณ„์† ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค.

์Šฌ๋กœ๊ทธ ์ค‘์˜ ํƒ€์ดํ‹€๊ณผ ์› ๋‚ด์šฉ์€ https://fsharpforfunandprofit.com/ ์˜ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

F#์œผ๋กœ 1๋ถ€ํ„ฐ n๊นŒ์ง€์˜ ์ œ๊ณฑ์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

let square x = x * x

let sumOfSquares n =
    [1..n] |> List.map square |> List.sum

let result = sumOfSquares 100
printfn "%A" result

์ด์— ํ•ด๋‹นํ•˜๋Š” C# ์ฝ”๋“œ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?

public static class SumOfSquaresHelper
{
   public static int Square(int i)
   {
      return i * i;
   }

   public static int SumOfSquares(int n)
   {
      int sum = 0;
      for (int i = 1; i <= n; i++)
      {
         sum += Square(i);
      }
      return sum;
   }
}

F#์€ C#์— ๋น„ํ•ด ๋‹ค์Œ์˜ ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋” ์ปดํŒฉํŠธ ํ•ฉ๋‹ˆ๋‹ค.
  • ์œ ํ˜• ์„ ์–ธ์ด ์—†์Šต๋‹ˆ๋‹ค.
  • ๋Œ€ํ™”ํ˜• ๊ฐœ๋ฐœ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ตœ์‹  C#์€ ์œ„์˜ ์ฝ”๋“œ ๋ณด๋‹ค ์ข€ ๋” F# ์ฒ˜๋Ÿผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

var square = (int x) => x * x;

var sumOfSquares = (int n) =>
    Enumerable.Range(1, n).Select(square).Sum();

var result = sumOfSquares(100);
Console.WriteLine(result);

LINQ์™€ ๊ทธ Fluent API ํ˜•ํƒœ, ๋žŒ๋‹ค ๋“ฑ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด์—์„œ ๋งŽ์ด ์˜ํ–ฅ ๋ฐ›์•˜๋‹ค๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๊ตฐ์š”!

C# ์ฝ”๋“œ๊ฐ€ ์ข€ ๋” ๊ฐ„๊ฒฐํ•ด์ง€๊ธด ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ F# ์ฝ”๋“œ๊ฐ€ ์ข€ ๋” ๊ฐ„๊ฒฐํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“  C#๋„ ๋งŽ์ด ๊ฐ„๊ฒฐํ•ด์กŒ๋„ค์š”!

3๊ฐœ์˜ ์ข‹์•„์š”

F#๊ณผ C# ๋น„๊ต : ์ •๋ ฌ

ํ€ต์†ŒํŠธ๋ฅผ ํ†ตํ•ด F#์˜ ๊ตฌํ˜„๊ณผ C#์˜ ๊ตฌํ˜„ ์ฐจ์ด๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค!

์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์–ธ์–ด ๋ณ„ ๊ตฌํ˜„๋œ ์ฝ”๋“œ๋ฅผ ๋น„๊ตํ•˜๋Š” ๋ชฉ์ ์œผ๋กœ ๋‹จ์ˆœํ™” ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ ํ€ต์†ŒํŠธ ๋กœ์ง์„ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ชฉ๋ก์ด ๋น„์–ด ์žˆ์œผ๋ฉด ํ•  ์ผ์ด ์—†์Œ. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ,
  • ๋ชฉ๋ก์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด
  • ๋‚˜๋จธ์ง€ ๋ชฉ๋ก์—์„œ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ณด๋‹ค ์ž‘์€ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์ฐพ์•„์„œ ์ •๋ ฌ
  • ๋ชฉ๋ก์˜ ๋‚˜๋จธ์ง€ ์š”์†Œ ์ค‘ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์ฐพ์•„์„œ ์ •๋ ฌ
  • ์„ธ ๋ถ€๋ถ„์„ ํ•ฉ์ณ์„œ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ์–ป์Œ (์ •๋ ฌ๋œ ์ž‘์€ ์š”์†Œ + ์ฒซ ๋ฒˆ์งธ ์š”์†Œ + ์ •๋ ฌ๋œ ํฐ ์š”์†Œ)

์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ F# ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

let rec quicksort list =
    match list with
    | [] -> []
    | firstElem::otherElements ->
        let smallerElements =
            otherElements
            |> List.filter (fun e -> e < firstElem)
            |> quicksort
        let largerElements =
            otherElements
            |> List.filter (fun e -> e >= firstElem)
            |> quicksort
        List.concat [smallerElements; [firstElem]; largerElements]

printfn "%A" (quicksort [1;5;23;18;9;1;3])

์ด์— ๋ฐ˜ํ•ด C# ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

public class QuickSortHelper
{
   public static List<T> QuickSort<T>(List<T> values)
      where T : IComparable
   {
      if (values.Count == 0)
      {
         return new List<T>();
      }

      T firstElement = values[0];

      var smallerElements = new List<T>();
      var largerElements = new List<T>();
      for (int i = 1; i < values.Count; i++)
      {
         var elem = values[i];
         if (elem.CompareTo(firstElement) < 0)
         {
            smallerElements.Add(elem);
         }
         else
         {
            largerElements.Add(elem);
         }
      }

      var result = new List<T>();
      result.AddRange(QuickSort(smallerElements.ToList()));
      result.Add(firstElement);
      result.AddRange(QuickSort(largerElements.ToList()));
      return result;
   }
}

์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋กœ์ง์„ ์ฝ”๋“œ๋กœ ์ „ํ™˜ํ•œ ๊ฒƒ์€ C# ์ฝ”๋“œ์— ๋น„ํ•ด F# ์ฝ”๋“œ๊ฐ€ ๋” ๋‚˜์•„ ๋ณด์ž…๋‹ˆ๋‹ค. (๋ฌผ๋ก , C#์˜ LINQ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์กฐ๊ธˆ์€ ๋ถˆ๊ณตํ‰ํ•œ ๋น„๊ต ๊ฐ™๊ธฐ๋Š” ํ•˜๋„ค์š”)

๋‹ค์Œ ์ฝ”๋“œ๋Š” LINQ์™€ ํ™•์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•œ ์ข€ ๋” ํ˜„๋Œ€์ (ํ•จ์ˆ˜ํ˜• ์Šคํƒ€์ผ)์ธ C# ์ž…๋‹ˆ๋‹ค.

public static class QuickSortExtension
{
    public static IEnumerable<T> QuickSort<T>(
        this IEnumerable<T> values) where T : IComparable
    {
        if (values == null || !values.Any())
        {
            return new List<T>();
        }

        var firstElement = values.First();
        var rest = values.Skip(1);

        var smallerElements = rest
                .Where(i => i.CompareTo(firstElement) < 0)
                .QuickSort();

        var largerElements = rest
                .Where(i => i.CompareTo(firstElement) >= 0)
                .QuickSort();

        return smallerElements
            .Concat(new List<T>{firstElement})
            .Concat(largerElements);
    }
}

์ฐธ๊ณ ๋กœ ๋‹ค์Œ์ฒ˜๋Ÿผ F# ์ฝ”๋“œ๋ฅผ ์ข€ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let rec quicksort2 = function
   | [] -> []
   | first::rest ->
        let smaller,larger = List.partition ((>=) first) rest
        List.concat [quicksort2 smaller; [first]; quicksort2 larger]

F# ์ฝ”๋“œ๊ฐ€ C# ์ฝ”๋“œ๋ณด๋‹ค ๋‚˜์€ ์ด์œ ๋Š” ๋กœ์ง์„ ๊ฑฐ์˜ ๊ทธ๋Œ€๋กœ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์œผ๋กœ ์„ ์–ธ์ (โ€œ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€โ€)์— ๋” ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  ๋ช…๋ น์ (โ€œ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋Š”์ง€โ€)์— ๋œ ์ง‘์ค‘ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

1๊ฐœ์˜ ์ข‹์•„์š”

์™ ์ง€ C#์ด ์ง„ ๋“ฏํ•˜์—ฌ ^^; (์ฃ„์†ก)

public static class IEnumerableExtensions
{
    public static IEnumerable<T> QuickSort<T>(this IEnumerable<T> source)
        where T : IComparable<T>  =>  source.Any() is false ? []
        : [
            ..source.Skip(1).Where(x => x.CompareTo(source.First()) < 0 ).ToList().QuickSort(),
            source.First(),
            ..source.Skip(1).Where(x => x.CompareTo(source.First()) >= 0 ).ToList().QuickSort()
        ];    
}
2๊ฐœ์˜ ์ข‹์•„์š”