What is Hackers' Pub?

Hackers' Pub is a place for software engineers to share their knowledge and experience with each other. It's also an ActivityPub-enabled social network, so you can follow your favorite hackers in the fediverse and get their latest posts in your feed.

0

docker-compose.yamlใ‚’ใใฎใพใพKubernetesใง็จผๅƒใ•ใ›ใ‚‹ใƒ„ใƒผใƒซใ€‚kappal up -dใงใ‚ตใƒผใƒ“ใ‚น็จผๅƒ้–‹ๅง‹ใ€‚้ข็™ฝใ„ใ€‚
---
GitHub - sandys/kappal
github.com/sandys/kappal

0

ๅ…ˆใปใฉใฎๅ†ๆŠ•็จฟใซใ‚ใฃใŸๆณจๆ„ๅ–š่ตทใ€ใ€Œใ‚จใ‚คใƒ–ใƒชใ‚บใƒ ่กจ็พ๏ผŸใ€ใจใฏๆ€ใฃใŸใ€‚็™บ้”้šœๅฎณใธใฎๅ่ฆ‹ใงใฏใ‚ใฃใฆใ‚‚ใ‚จใ‚คใƒ–ใƒชใ‚บใƒ ใจใฏ้•ใตใฎใงใฏ๏ผŸ

0
1
1
1
0
0
0
0
0

TLใง่ฆ‹ใ‹ใ‘ใŸใƒใƒงใ‚ณๆƒ…ๅ ฑใ‚’็‰‡ใฃ็ซฏใ‹ใ‚‰ๆคœ็ดขใ‹ใ‘ใฆ่ฒทใฃใฆ้ฃŸในๆฏ”ในใ‚‹ใ‹ใฃใฆใชใฃใฆใ‚‹ใ‚“ใ ใ‘ใฉใ€ๅ…จ้ƒจ่ฒทใฃใŸใ‚‰2ไธ‡ใใ‚‰ใ„ใซใชใ‚‰ใชใ„ใ“ใ‚Œ๏ผŸใฃใฆใชใฃใฆใ‚‹ใ€‚

1

Some people collect stamps; we at CSS Day collect browser vendors. We already announced Vivaldi and Ladybird; today we add Google and Microsoft.

This allows our attendees to complain efficiently about CSS problems in many browsers at once, while their representatives smile, take notes, apologise, and promise to do better.

Today we announce the following speakers:

- @patrickbrosset (Microsoft)
- @UnaUna Kravets (Google)
- and @argyleinkAdam Argyle (CSS)

See our full line-up at cssday.nl

0
1

- AI ์‹œ์Šคํ…œ์€ ์ด์ œ ์ž์‹ ์ด ๋งํ•œ ๊ฒƒ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ˆ˜ํ•˜์ง€ ์•Š๊ณ  ์œ ์ฐฝํ•œ ์–ธ์–ด๋ฅผ ์ƒ์„ฑ

- ์ฑ—๋ด‡์ด ์‚ฌ๊ณผํ•˜๊ณ , ์•ฝ์†ํ•˜๊ณ , ์„ค๋“๋ ฅ ์žˆ๊ฒŒ ์กฐ์–ธํ•  ๋•Œ ์ด๋Ÿฌํ•œ ๋ง ๋’ค์—๋Š” ์•„๋ฌด๋„ ์—†์Œ

- ์ด๋Š” ์ฑ…์ž„๊ฐ, ์ธ๊ฐ„์˜ ์กด์—„์„ฑ, ํ™”์ž๋ฅผ ์ž์‹ ์˜ ๋ง์— ๋ฌถ๋Š” ์‚ฌํšŒ ๊ณ„์•ฝ์„ ์นจ์‹ํ•จ

- ์ฑ…์ž„, ์ €์ž‘๊ถŒ, ๋ช…ํ™•ํ•œ ์ฑ…์ž„ ์†Œ์žฌ๋ฅผ ๋ณด์กดํ•  ์ƒˆ๋กœ์šด ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•จ

Words Without Consequence - The Atlantic

https://www.theatlantic.com/technology/2026/02/words-without-consequence/685974/

0
0
0
0

RE: social.wake.st/@liaizon/116085

It is a good strategy, but more importantly, it gives people the agency to choose what platforms and protocols they want to use while still finding the communities they need to.

I wrote about it a couple years ago: augment.ink/bridges-the-last-n

0
0
0

๊ฑ ๋ฒˆ์—ญ๊ธฐ ๋Œ๋ฆฌ๊ณ  ๋ฌธ์ œ ์—†์œผ๋ฉด ์˜ฌ๋ฆฌ๋Š” ์‹์œผ๋กœ ํ•˜๋ฉด ๊ธˆ๋ฐฉ๊ธˆ๋ฐฉ ๋๋‚  ์ค„ ์•Œ์•˜๋Š”๋ฐ ๋ฒˆ์—ญ๋œ ๊ธ€ ์ฝ๋Š” ๊ฒƒ๋„ ์€๊ทผ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋„ค ใ…‹ใ…‹ใ…‹...

https://hackers.pub/@2chanhaeng/2026/functional-programming-in-lean-ํ•œ๊ตญ์–ด-๋ฒˆ์—ญ-1-lean-์•Œ์•„๋ณด๊ธฐ

Functional Programming in Lean ํ•œ๊ตญ์–ด ๋ฒˆ์—ญ - 1. Lean ์•Œ์•„๋ณด๊ธฐ

Note ์ด ๊ธ€์€ Lean ๊ณต์‹ ๋ฌธ์„œ์— ์†Œ๊ฐœ๋œ Functional Programming in Lean์„ ์ž‘์„ฑ์ž๊ฐ€ ์ฝ๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ Kagi Translate๋ฅผ ํ†ตํ•ด 1์ฐจ๋กœ ๊ธฐ๊ณ„ ๋ฒˆ์—ญ ํ›„ ๋ณด์™„ํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.์›๋ฌธ๊ณผ์˜ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ •์‹ ๋‚ด์šฉ์€ ํ•ญ์ƒ ์›๋ฌธ์„ ํ†ตํ•ด ํ™•์ธ ๋ฐ”๋ž๋‹ˆ๋‹ค.์›๋ฌธ์ด Creative Commons Attribution 4.0 International License๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐฐํฌ๋œ ๊ฒƒ์„ ์กด์ค‘ํ•˜์—ฌ ์ด ๊ธ€ ๋˜ํ•œ CC BY 4.0 ํ•˜์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. 1. Lean ์•Œ์•„๋ณด๊ธฐ ์ „ํ†ต์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋Š” ์ฝ˜์†”์— "Hello, world!"๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ปดํŒŒ์ผํ•˜๊ณ  ์‹คํ–‰ํ•จ์œผ๋กœ์จ ์†Œ๊ฐœ๋˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋žจ์€ ์–ธ์–ด ๋„๊ตฌ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์น˜๋˜์—ˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ปดํŒŒ์ผ๋œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•ด ์ค๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ 1970๋…„๋Œ€ ์ดํ›„๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋ณ€ํ™”ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜๋‚  ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋Œ€๊ฐœ ํ…์ŠคํŠธ ์—๋””ํ„ฐ์— ํ†ตํ•ฉ๋˜์–ด ์žˆ์œผ๋ฉฐ, ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ™˜๊ฒฝ์€ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜๋Š” ๋™์•ˆ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Lean๋„ ์˜ˆ์™ธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. Lean์€ ์–ธ์–ด ์„œ๋ฒ„ ํ”„๋กœํ† ์ฝœ ์˜ ํ™•์žฅ ๋ฒ„์ „์„ ๊ตฌํ˜„ํ•˜์—ฌ ํ…์ŠคํŠธ ์—๋””ํ„ฐ์™€ ํ†ต์‹ ํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•˜๋Š” ๋™์•ˆ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. Python, Haskell, JavaScript์™€ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ์–ธ์–ด๋“ค์€ ํ‘œํ˜„์‹์ด๋‚˜ ๋ฌธ์žฅ์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” REPL, ์ฆ‰ ๋Œ€ํ™”ํ˜• ํ†ฑ๋ ˆ๋ฒจ์ด๋‚˜ ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์–ธ์–ด๋Š” ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด Lean์€ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์—๋””ํ„ฐ์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์— ํ†ตํ•ฉํ•˜์—ฌ, ํ…์ŠคํŠธ ์—๋””ํ„ฐ๊ฐ€ ํ”„๋กœ๊ทธ๋žจ ํ…์ŠคํŠธ ์ž์ฒด์— ํ†ตํ•ฉ๋œ ํ”ผ๋“œ๋ฐฑ์„ ํ‘œ์‹œํ•˜๋„๋ก ํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์žฅ์—์„œ๋Š” ์—๋””ํ„ฐ์—์„œ Lean๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์งง๊ฒŒ ์†Œ๊ฐœํ•˜๋ฉฐ, Hello, World! ์žฅ์—์„œ๋Š” ๋ช…๋ น์ค„์—์„œ ๋ฐฐ์น˜ ๋ชจ๋“œ๋กœ Lean์„ ์‚ฌ์šฉํ•˜๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์—๋””ํ„ฐ์— Lean์„ ๋„์›Œ ๋†“๊ณ  ๊ฐ ์˜ˆ์ œ๋ฅผ ์ง์ ‘ ์ž…๋ ฅํ•˜๋ฉฐ ์ด ์ฑ…์„ ์ฝ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ๋“ค์„ ์ง์ ‘ ๋‹ค๋ฃจ์–ด ๋ณด๋ฉฐ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”! 1.1. ํ‘œํ˜„์‹ ํ‰๊ฐ€ํ•˜๊ธฐ Lean์„ ๋ฐฐ์šฐ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋กœ์„œ ์ดํ•ดํ•ด์•ผ ํ•  ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ํ‰๊ฐ€๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์ž…๋‹ˆ๋‹ค. ํ‰๊ฐ€๋Š” ์‚ฐ์ˆ˜์—์„œ์ฒ˜๋Ÿผ ํ‘œํ˜„์‹์˜ ๊ฐ’์„ ์ฐพ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 15โˆ’615โˆ’6์˜ ๊ฐ’์€ 99์ด๊ณ  2ร—(3+1)2ร—(3+1)์˜ ๊ฐ’์€ 88์ž…๋‹ˆ๋‹ค. ํ›„์ž์˜ ํ‘œํ˜„์‹ ๊ฐ’์„ ์ฐพ๊ธฐ ์œ„ํ•ด, 3+13+1์€ ๋จผ์ € 44๋กœ ๋Œ€์ฒด๋˜์–ด 2ร—42ร—4๊ฐ€ ๋˜๊ณ , ์ด๋Š” ๋‹ค์‹œ 88๋กœ ์ค„์–ด๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ ์ˆ˜ํ•™์  ํ‘œํ˜„์‹์—๋Š” ๋ณ€์ˆ˜๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. x+1x+1์˜ ๊ฐ’์€ xx์˜ ๊ฐ’์„ ์•Œ๊ธฐ ์ „๊นŒ์ง€๋Š” ๊ณ„์‚ฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Lean์—์„œ ํ”„๋กœ๊ทธ๋žจ์€ ๋ฌด์—‡๋ณด๋‹ค๋„ ํ‘œํ˜„์‹์ด๋ฉฐ, ๊ณ„์‚ฐ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ์ฃผ๋œ ๋ฐฉ์‹์€ ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜์—ฌ ๊ทธ ๊ฐ’์„ ์ฐพ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋Š” ๋ช…๋ นํ˜•์œผ๋กœ, ํ”„๋กœ๊ทธ๋žจ์€ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•  ์ผ๋ จ์˜ ๋ฌธ์žฅ๋“ค๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ณ€์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๊ฐ’์€ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ ์™ธ์—๋„, ํ”„๋กœ๊ทธ๋žจ์€ ํŒŒ์ผ ์‚ญ์ œ, ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ, ์˜ˆ์™ธ ๋ฐœ์ƒ ๋˜๋Š” ์ฒ˜๋ฆฌ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ถ€์ž‘์šฉ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "๋ถ€์ž‘์šฉ"์€ ๋ณธ์งˆ์ ์œผ๋กœ ์ˆ˜ํ•™์  ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ชจ๋ธ์„ ๋”ฐ๋ฅด์ง€ ์•Š๋Š” ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š” ์ผ๋“ค์„ ์„ค๋ช…ํ•˜๋Š” ํฌ๊ด„์ ์ธ ์šฉ์–ด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Lean์—์„œ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์ˆ˜ํ•™์  ํ‘œํ˜„์‹๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋‹จ ๊ฐ’์ด ์ฃผ์–ด์ง€๋ฉด ๋ณ€์ˆ˜๋Š” ์žฌํ• ๋‹น๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๋ถ€์ž‘์šฉ์„ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‘ ํ‘œํ˜„์‹์ด ๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง€๋ฉด, ํ•˜๋‚˜๋ฅผ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋Œ€์ฒดํ•ด๋„ ํ”„๋กœ๊ทธ๋žจ์ด ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๊ณ„์‚ฐํ•˜๊ฒŒ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด Lean์œผ๋กœ ์ฝ˜์†”์— Hello, world!๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹ˆ์ง€๋งŒ, ์ž…์ถœ๋ ฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์€ Lean์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝํ—˜์˜ ํ•ต์‹ฌ์ ์ธ ๋ถ€๋ถ„์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์žฅ์—์„œ๋Š” Lean์œผ๋กœ ํ‘œํ˜„์‹์„ ๋Œ€ํ™”์‹์œผ๋กœ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ์ดˆ์ ์„ ๋งž์ถ”๊ณ , ๋‹ค์Œ ์žฅ์—์„œ๋Š” Hello, world! ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑ, ์ปดํŒŒ์ผ ๋ฐ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. Lean์—๊ฒŒ ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜๋„๋ก ์š”์ฒญํ•˜๋ ค๋ฉด, ํŽธ์ง‘๊ธฐ์—์„œ ๊ทธ ์•ž์— #eval์„ ์ž‘์„ฑํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค์‹œ ๋ณด๊ณ ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฒฐ๊ณผ๋Š” #eval ์œ„์— ์ปค์„œ๋‚˜ ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ๋ฅผ ์˜ฌ๋ ค๋†“์œผ๋ฉด ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, #eval 1 + 2 ๋Š” ๋‹ค์Œ ๊ฐ’์„ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. 3 Lean์€ ์‚ฐ์ˆ  ์—ฐ์‚ฐ์ž์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ ์šฐ์„ ์ˆœ์œ„ ๋ฐ ๊ฒฐํ•ฉ์„ฑ ๊ทœ์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ฆ‰, #eval 1 + 2 * 5 ๋Š” 15๊ฐ€ ์•„๋‹Œ 11์ด๋ผ๋Š” ๊ฐ’์„ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์ˆ˜ํ•™ ํ‘œ๊ธฐ๋ฒ•๊ณผ ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜์— ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ด„ํ˜ธ(์˜ˆ: f(x))๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ˜๋ฉด, Lean์€ ๋‹จ์ˆœํžˆ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜ ์˜†์— ์”๋‹ˆ๋‹ค(์˜ˆ: f x). ํ•จ์ˆ˜ ์ ์šฉ์€ ๊ฐ€์žฅ ํ”ํ•œ ์—ฐ์‚ฐ ์ค‘ ํ•˜๋‚˜์ด๋ฏ€๋กœ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. "Hello, Lean!"์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด #eval String.append("Hello, ", "Lean!") ๋ผ๊ณ  ์“ฐ๋Š” ๋Œ€์‹ , ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์”๋‹ˆ๋‹ค. #eval String.append "Hello, " "Lean!" ์—ฌ๊ธฐ์„œ ํ•จ์ˆ˜์˜ ๋‘ ์ธ์ˆ˜๋Š” ๋‹จ์ˆœํžˆ ๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์˜†์— ์”๋‹ˆ๋‹ค. ์‚ฐ์ˆ ์˜ ์—ฐ์‚ฐ ์ˆœ์„œ ๊ทœ์น™์ด (1 + 2) * 5 ํ‘œํ˜„์‹์—์„œ ๊ด„ํ˜ธ๋ฅผ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํ†ตํ•ด ๊ณ„์‚ฐ๋˜์–ด์•ผ ํ•  ๋•Œ๋„ ๊ด„ํ˜ธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ํ‘œํ˜„์‹์—์„œ๋Š” ๊ด„ํ˜ธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. #eval String.append "great " (String.append "oak " "tree") ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‘ ๋ฒˆ์งธ String.append๋Š” "oak "์™€ "tree"๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ์ฒซ ๋ฒˆ์งธ String.append์˜ ์ธ์ˆ˜๋กœ ํ•ด์„๋  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‚ด๋ถ€ String.append ํ˜ธ์ถœ์˜ ๊ฐ’์„ ๋จผ์ € ์ฐพ์•„์•ผ ํ•˜๋ฉฐ, ๊ทธ ํ›„์— "great "์— ๋ง๋ถ™์—ฌ์ ธ ์ตœ์ข… ๊ฐ’ "great oak tree"๋ฅผ ์‚ฐ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช…๋ นํ˜• ์–ธ์–ด๋Š” ์ข…์ข… ๋‘ ์ข…๋ฅ˜์˜ ์กฐ๊ฑด๋ฌธ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์— ๋”ฐ๋ผ ์–ด๋–ค ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์กฐ๊ฑด๋ฌธ์ด๊ณ , ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์— ๋”ฐ๋ผ ๋‘ ํ‘œํ˜„์‹ ์ค‘ ์–ด๋А ๊ฒƒ์„ ํ‰๊ฐ€ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์กฐ๊ฑด ํ‘œํ˜„์‹์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, C์™€ C++์—์„œ๋Š” ์กฐ๊ฑด๋ฌธ์ด if์™€ else๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋˜๋Š” ๋ฐ˜๋ฉด, ์กฐ๊ฑด ํ‘œํ˜„์‹์€ ?์™€ :๊ฐ€ ์กฐ๊ฑด์„ ๋ถ„๊ธฐ์—์„œ ๋ถ„๋ฆฌํ•˜๋Š” ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋กœ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ์—์„œ๋Š” ์กฐ๊ฑด๋ฌธ์ด if๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ˜๋ฉด, ์กฐ๊ฑด ํ‘œํ˜„์‹์€ if๋ฅผ ์ค‘๊ฐ„์— ๋‘ก๋‹ˆ๋‹ค. Lean์€ ํ‘œํ˜„์‹ ์ค‘์‹ฌ์˜ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์กฐ๊ฑด๋ฌธ์€ ์—†๊ณ  ์กฐ๊ฑด ํ‘œํ˜„์‹๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ๋“ค์€ if, then, else๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด,String.append "it is " (if 1 > 2 then "yes" else "no") ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค.String.append "it is " (if false then "yes" else "no") ์ด๋Š” ๋‹ค์‹œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค.String.append "it is " "no" ๊ทธ๋ฆฌ๊ณ  ์ตœ์ข…์ ์œผ๋กœ "it is no"๋กœ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ๊ฐ„๊ฒฐํ•จ์„ ์œ„ํ•ด, ์ด์™€ ๊ฐ™์€ ์ผ๋ จ์˜ ํ‰๊ฐ€ ๋‹จ๊ณ„๋Š” ๋•Œ๋•Œ๋กœ ํ™”์‚ดํ‘œ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.String.append "it is " (if 1 > 2 then "yes" else "no")String.append "it is " (if false then "yes" else "no")String.append "it is " "no""it is no" 1.1.1. ๋งˆ์ฃผ์น  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์‹œ์ง€ ์ธ์ˆ˜๊ฐ€ ๋ˆ„๋ฝ๋œ ํ•จ์ˆ˜ ์ ์šฉ์„ Lean์—๊ฒŒ ํ‰๊ฐ€ํ•˜๋„๋ก ์š”์ฒญํ•˜๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ, ๋‹ค์Œ ์˜ˆ์ œ๋Š” #eval String.append "it is " ์ƒ๋‹นํžˆ ๊ธด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. could not synthesize a `ToExpr`, `Repr`, or `ToString` instance for type String โ†’ String ์ด ๋ฉ”์‹œ์ง€๋Š” Lean ํ•จ์ˆ˜๊ฐ€ ์ผ๋ถ€ ์ธ์ˆ˜์—๋งŒ ์ ์šฉ๋  ๋•Œ ๋‚˜๋จธ์ง€ ์ธ์ˆ˜๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. Lean์€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ‘œ์‹œํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ๊ทธ๋ ‡๊ฒŒ ํ•˜๋„๋ก ์š”์ฒญ๋ฐ›์•˜์„ ๋•Œ ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. 1.1.2. ์—ฐ์Šต ๋ฌธ์ œ ๋‹ค์Œ ํ‘œํ˜„์‹๋“ค์˜ ๊ฐ’์€ ๋ฌด์—‡์ผ๊นŒ์š”? ์†์œผ๋กœ ํ’€์–ด๋ณธ ๋‹ค์Œ, Lean์— ์ž…๋ ฅํ•˜์—ฌ ๋‹ต์„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. 42 + 19 String.append "A" (String.append "B" "C") String.append (String.append "A" "B") "C" if 3 == 3 then 5 else 7 if 3 == 4 then "equal" else "not equal" 1.2. ํƒ€์ž… ํƒ€์ž…์€ ํ”„๋กœ๊ทธ๋žจ์ด ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์„ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž…์€ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์—ฌ๋Ÿฌ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ’์˜ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด ํ‘œํ˜„์— ๋Œ€ํ•ด ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ ์ž์‹ ์˜ ์˜๋„๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ๋ฉฐ, ํ•จ์ˆ˜์˜ ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์— ๋Œ€ํ•œ ๊ฐ€๋ฒผ์šด ๋ช…์„ธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด ์ด ๋ช…์„ธ๋ฅผ ์ค€์ˆ˜ํ•˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ˆซ์ž์— ๋ฌธ์ž์—ด์„ ๋”ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ์ž ์žฌ์  ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์— ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ์˜ ์ˆ˜๋ฅผ ์ค„์—ฌ์ค๋‹ˆ๋‹ค. Lean ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ƒ์šฉ๊ตฌ ์ฝ”๋“œ๋ฅผ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋Š” ๋ณด์กฐ ์ฝ”๋“œ ์ƒ์„ฑ์„ ์ž๋™ํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. Lean์˜ ํƒ€์ž… ์‹œ์Šคํ…œ์€ ์ด๋ก€์ ์œผ๋กœ ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž…์€ "์ด ์ •๋ ฌ ํ•จ์ˆ˜๋Š” ์ž…๋ ฅ์˜ ์ˆœ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค"์™€ ๊ฐ™์€ ๊ฐ•๋ ฅํ•œ ๋ช…์„ธ๋‚˜ "์ด ํ•จ์ˆ˜๋Š” ์ธ์ˆ˜์˜ ๊ฐ’์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ๊ฐ–๋Š”๋‹ค"์™€ ๊ฐ™์€ ์œ ์—ฐํ•œ ๋ช…์„ธ๋ฅผ ์ธ์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํƒ€์ž… ์‹œ์Šคํ…œ์€ ์‹ฌ์ง€์–ด ์ˆ˜ํ•™์  ์ •๋ฆฌ๋ฅผ ์ฆ๋ช…ํ•˜๊ธฐ ์œ„ํ•œ ์™„์ „ํ•œ ๋…ผ๋ฆฌ๋กœ๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ์ตœ์ฒจ๋‹จ ํ‘œํ˜„๋ ฅ์ด ๋” ๊ฐ„๋‹จํ•œ ํƒ€์ž…์„ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ, ์ด๋Ÿฌํ•œ ๋” ๊ฐ„๋‹จํ•œ ํƒ€์ž…์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ๋” ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ „์ œ ์กฐ๊ฑด์ž…๋‹ˆ๋‹ค. Lean์˜ ๋ชจ๋“  ํ”„๋กœ๊ทธ๋žจ์€ ํƒ€์ž…์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ, ๋ชจ๋“  ํ‘œํ˜„์‹์€ ํ‰๊ฐ€๋˜๊ธฐ ์ „์— ํƒ€์ž…์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€์˜ ์˜ˆ์ œ์—์„œ๋Š” Lean์ด ์Šค์Šค๋กœ ํƒ€์ž…์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ, ๋•Œ๋กœ๋Š” ํƒ€์ž…์„ ์ œ๊ณตํ•ด์•ผ ํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ด„ํ˜ธ ์•ˆ์—์„œ ์ฝœ๋ก  ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. #eval (1 + 2 : Nat) ์—ฌ๊ธฐ์„œ Nat์€ ์ž์—ฐ์ˆ˜์˜ ํƒ€์ž…์œผ๋กœ, ์ž„์˜ ์ •๋ฐ€๋„์˜ ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜์ž…๋‹ˆ๋‹ค. Lean์—์„œ Nat์€ ์Œ์ˆ˜๊ฐ€ ์•„๋‹Œ ์ •์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด์˜ ๊ธฐ๋ณธ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ณธ ํƒ€์ž…์ด ํ•ญ์ƒ ์ตœ์„ ์˜ ์„ ํƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. C์—์„œ๋Š” ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜๊ฐ€ ๋บ„์…ˆ ๊ฒฐ๊ณผ๊ฐ€ 0๋ณด๋‹ค ์ž‘์•„์งˆ ๊ฒฝ์šฐ ํ‘œํ˜„ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ํฐ ์ˆ˜๋กœ ์–ธ๋”ํ”Œ๋กœ์šฐ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Nat์€ ์ž„์˜๋กœ ํฐ ๋ถ€ํ˜ธ ์—†๋Š” ์ˆ˜๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์–ธ๋”ํ”Œ๋กœ์šฐ๋  ๊ฐ€์žฅ ํฐ ์ˆ˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Nat์—์„œ์˜ ๋บ„์…ˆ์€ ๊ฒฐ๊ณผ๊ฐ€ ์Œ์ˆ˜์˜€์„ ๊ฒฝ์šฐ 0์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, #eval (1 - 2 : Nat) ๋Š” -1์ด ์•„๋‹Œ 0์œผ๋กœ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์Œ์˜ ์ •์ˆ˜๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ง์ ‘ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค. #eval (1 - 2 : Int) ์ด ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฐ๊ณผ๋Š” ์˜ˆ์ƒ๋Œ€๋กœ -1์ด ๋ฉ๋‹ˆ๋‹ค. ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ํƒ€์ž…์„ ํ™•์ธํ•˜๋ ค๋ฉด #eval ๋Œ€์‹  #check๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ์˜ˆ๋ฅผ ๋“ค์–ด: #check (1 - 2 : Int) ๋Š” ์‹ค์ œ๋กœ ๋บ„์…ˆ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ  1 - 2 : Int๋ฅผ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์— ํƒ€์ž…์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์—†์„ ๋•Œ๋Š” #check์™€ #eval ๋ชจ๋‘์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด: #check String.append ["hello", " "] "world" ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. Application type mismatch: The argument ["hello", " "]has type List Stringbut is expected to have type Stringin the application String.append ["hello", " "] String.append์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๋ฌธ์ž์—ด์ด์–ด์•ผ ํ•˜๋Š”๋ฐ ๋ฌธ์ž์—ด ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋Œ€์‹  ์ œ๊ณต๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 1.3. ํ•จ์ˆ˜์™€ ์ •์˜ Lean์—์„œ๋Š” def ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, hello๋ผ๋Š” ์ด๋ฆ„์„ ๋ฌธ์ž์—ด "Hello"๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ์ •์˜ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. def hello := "Hello" Lean์—์„œ๋Š” ์ƒˆ๋กœ์šด ์ด๋ฆ„์„ ์ •์˜ํ•  ๋•Œ = ๋Œ€์‹  ์ฝœ๋ก -๋“ฑํ˜ธ ์—ฐ์‚ฐ์ž :=๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” =๊ฐ€ ๊ธฐ์กด ํ‘œํ˜„์‹ ๊ฐ„์˜ ๋™๋“ฑ์„ฑ์„ ์„ค๋ช…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ˜ผ๋™์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. hello์˜ ์ •์˜์—์„œ, ํ‘œํ˜„์‹ "Hello"๋Š” Lean์ด ์ •์˜์˜ ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€๋ถ€๋ถ„์˜ ์ •์˜๋Š” ๊ทธ๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๋ณดํ†ต ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ •์˜๋˜๋Š” ์ด๋ฆ„ ๋’ค์— ์ฝœ๋ก ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. def lean : String := "Lean" ์ด์ œ ์ด๋ฆ„์ด ์ •์˜๋˜์—ˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ #eval String.append hello (String.append " " lean) ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค. "Hello Lean" Lean์—์„œ๋Š” ์ •์˜๋œ ์ด๋ฆ„์€ ์ •์˜๋œ ์ดํ›„์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ์–ธ์–ด์—์„œ ํ•จ์ˆ˜ ์ •์˜๋Š” ๋‹ค๋ฅธ ๊ฐ’์˜ ์ •์˜์™€ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŒŒ์ด์ฌ ํ•จ์ˆ˜ ์ •์˜๋Š” def ํ‚ค์›Œ๋“œ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค๋ฅธ ์ •์˜๋Š” ๋“ฑํ˜ธ๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค. Lean์—์„œ๋Š” ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ๊ฐ’๊ณผ ๋™์ผํ•œ def ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , hello์™€ ๊ฐ™์€ ์ •์˜๋Š” ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ๋™๋“ฑํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ธ์ˆ˜๊ฐ€ ์—†๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ, ๊ทธ ๊ฐ’ ์ž์ฒด๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•˜๋Š” ์ด๋ฆ„์„ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. 1.3.1. ํ•จ์ˆ˜ ์ •์˜ํ•˜๊ธฐ Lean์—์„œ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ์ •์˜์˜ ํƒ€์ž… ์•ž์— ๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ธ์ˆ˜์— 1์„ ๋”ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def add1 (n : Nat) : Nat := n + 1 #eval๋กœ ์ด ํ•จ์ˆ˜๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ฉด ์˜ˆ์ƒ๋Œ€๋กœ 8์ด ๋‚˜์˜ต๋‹ˆ๋‹ค. #eval add1 7 ํ•จ์ˆ˜๊ฐ€ ๊ฐ ์ธ์ˆ˜ ์‚ฌ์ด์— ๊ณต๋ฐฑ์„ ์จ์„œ ์—ฌ๋Ÿฌ ์ธ์ˆ˜์— ์ ์šฉ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์—ฌ๋Ÿฌ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜๋Š” ์ธ์ˆ˜์˜ ์ด๋ฆ„๊ณผ ํƒ€์ž… ์‚ฌ์ด์— ๊ณต๋ฐฑ์„ ๋‘์–ด ์ •์˜๋ฉ๋‹ˆ๋‹ค. maximum ํ•จ์ˆ˜๋Š” ๋‘ ์ธ์ˆ˜ n๊ณผ k ์ค‘ ๋” ํฐ ๊ฐ’๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋ฉฐ, ๋‘ ๊ฐœ์˜ Nat ์ธ์ˆ˜๋ฅผ ๋ฐ›์•„ Nat๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. def maximum (n : Nat) (k : Nat) : Nat := if n < k then k else n ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, spaceBetween ํ•จ์ˆ˜๋Š” ๋‘ ๋ฌธ์ž์—ด ์‚ฌ์ด์— ๊ณต๋ฐฑ์„ ๋„ฃ์–ด ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. def spaceBetween (before : String) (after : String) : String := String.append before (String.append " " after) maximum๊ณผ ๊ฐ™์€ ์ •์˜๋œ ํ•จ์ˆ˜์— ์ธ์ˆ˜๊ฐ€ ์ œ๊ณต๋˜๋ฉด, ๊ฒฐ๊ณผ๋Š” ๋จผ์ € ๋ณธ๋ฌธ์—์„œ ์ธ์ˆ˜ ์ด๋ฆ„์„ ์ œ๊ณต๋œ ๊ฐ’์œผ๋กœ ๋ฐ”๊พผ ๋‹ค์Œ, ๊ฒฐ๊ณผ ๋ณธ๋ฌธ์„ ํ‰๊ฐ€ํ•˜์—ฌ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. maximum (5 + 8) (2 * 7) โ€…โ€ŠโŸนโ€…โ€Š\implies maximum 13 14 โ€…โ€ŠโŸนโ€…โ€Š\implies if 13 < 14 then 14 else 13 โ€…โ€ŠโŸนโ€…โ€Š\implies 14 ์ž์—ฐ์ˆ˜, ์ •์ˆ˜, ๋ฌธ์ž์—ด๋กœ ํ‰๊ฐ€๋˜๋Š” ํ‘œํ˜„์‹์€ ์ด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํƒ€์ž…(Nat, Int, String ๋“ฑ)์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ด๋Š” ํ•จ์ˆ˜์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. Nat๋ฅผ ๋ฐ›์•„ Bool์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” Nat โ†’ Bool ํƒ€์ž…์„ ๊ฐ€์ง€๋ฉฐ, ๋‘ ๊ฐœ์˜ Nat๋ฅผ ๋ฐ›์•„ Nat๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” Nat โ†’ Nat โ†’ Nat ํƒ€์ž…์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๋กœ, Lean์€ #check์™€ ํ•จ๊ป˜ ์ด๋ฆ„์ด ์ง์ ‘ ์‚ฌ์šฉ๋  ๋•Œ ํ•จ์ˆ˜์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. #check add1์„ ์ž…๋ ฅํ•˜๋ฉด add1 (n : Nat) : Nat๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์„ ๊ด„ํ˜ธ ์•ˆ์— ์จ์„œ ํ•จ์ˆ˜๋ฅผ ์ผ๋ฐ˜ ํ‘œํ˜„์‹์œผ๋กœ ์ทจ๊ธ‰ํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ Lean์„ "์†์—ฌ" ํ•จ์ˆ˜์˜ ํƒ€์ž…์„ ํ‘œ์‹œํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ #check (add1)์€ add1 : Nat โ†’ Nat๋ฅผ, #check (maximum)์€ maximum : Nat โ†’ Nat โ†’ Nat๋ฅผ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด ํ™”์‚ดํ‘œ๋Š” ASCII ๋Œ€์ฒด ํ™”์‚ดํ‘œ ->๋กœ๋„ ์“ธ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์•ž์„  ํ•จ์ˆ˜ ํƒ€์ž…์€ ๊ฐ๊ฐ example : Nat -> Nat := add1๊ณผ example : Nat -> Nat -> Nat := maximum์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ์‹ค์ œ๋กœ๋Š” ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์ธ์ˆ˜๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. maximum์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ํ•จ์ˆ˜๋Š” ์‚ฌ์‹ค ํ•˜๋‚˜์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›๊ณ  ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋Š” ๋‹ค์Œ ์ธ์ˆ˜๋ฅผ ๋ฐ›๊ณ , ๋” ์ด์ƒ ๊ธฐ๋Œ€๋˜๋Š” ์ธ์ˆ˜๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ์ด ๊ณผ์ •์ด ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์—ฌ๋Ÿฌ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์— ํ•˜๋‚˜์˜ ์ธ์ˆ˜๋ฅผ ์ œ๊ณตํ•จ์œผ๋กœ์จ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #check maximum 3์€ maximum 3 : Nat โ†’ Nat๋ฅผ, #check spaceBetween "Hello "๋Š” spaceBetween "Hello " : String โ†’ String์„ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์ค‘ ์ธ์ˆ˜ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์ˆ˜ํ•™์ž ํ•˜์Šค์ผˆ ์ปค๋ฆฌ์˜ ์ด๋ฆ„์„ ๋”ฐ์„œ ์ปค๋ง(currying)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ํ™”์‚ดํ‘œ๋Š” ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ฒฐํ•ฉํ•˜๋ฏ€๋กœ, Nat โ†’ Nat โ†’ Nat๋Š” Nat โ†’ (Nat โ†’ Nat)๋กœ ๊ด„ํ˜ธ๋ฅผ ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค. 1.3.1.1. ์—ฐ์Šต ๋ฌธ์ œ String โ†’ String โ†’ String โ†’ String ํƒ€์ž…์˜ joinStringsWith ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์„ธ์š”. ์ด ํ•จ์ˆ˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๋‘ ๋ฒˆ์งธ์™€ ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜ ์‚ฌ์ด์— ๋„ฃ์–ด ์ƒˆ๋กœ์šด ๋ฌธ์ž์—ด์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. joinStringsWith ", " "one" "and another"๋Š” "one, and another"๋กœ ํ‰๊ฐ€๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. joinStringsWith ": "์˜ ํƒ€์ž…์€ ๋ฌด์—‡์ผ๊นŒ์š”? Lean์œผ๋กœ ๋‹ต์„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. ์ฃผ์–ด์ง„ ๋†’์ด, ๋„ˆ๋น„, ๊นŠ์ด๋กœ ์ง์œก๋ฉด์ฒด์˜ ๋ถ€ํ”ผ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” Nat โ†’ Nat โ†’ Nat โ†’ Nat ํƒ€์ž…์˜ volume ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์„ธ์š”. 1.3.2. ํƒ€์ž… ์ •์˜ํ•˜๊ธฐ ๋Œ€๋ถ€๋ถ„์˜ ํƒ€์ž…์ด ์žˆ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—๋Š” C์˜ typedef์™€ ๊ฐ™์ด ํƒ€์ž…์— ๋Œ€ํ•œ ๋ณ„์นญ์„ ์ •์˜ํ•˜๋Š” ์ˆ˜๋‹จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Lean์—์„œ๋Š” ํƒ€์ž…์ด ์–ธ์–ด์˜ ์ผ๊ธ‰(first-class) ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ํƒ€์ž…์€ ๋‹ค๋ฅธ ํ‘œํ˜„์‹๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ •์˜๊ฐ€ ๋‹ค๋ฅธ ๊ฐ’๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํƒ€์ž…๋„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, String์„ ์ž…๋ ฅํ•˜๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ๋‹ค๋ฉด, ๋” ์งง์€ ์•ฝ์–ด Str์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def Str : Type := String ๊ทธ๋Ÿฌ๋ฉด String ๋Œ€์‹  Str์„ ์ •์˜์˜ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def aStr : Str := "This is a string." ์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋Š” ์ด์œ ๋Š” ํƒ€์ž…์ด Lean์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„๊ณผ ๋™์ผํ•œ ๊ทœ์น™์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํƒ€์ž…์€ ํ‘œํ˜„์‹์ด๋ฉฐ, ํ‘œํ˜„์‹์—์„œ ์ •์˜๋œ ์ด๋ฆ„์€ ๊ทธ ์ •์˜๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Str์ด String์„ ์˜๋ฏธํ•˜๋„๋ก ์ •์˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— aStr์˜ ์ •์˜๋Š” ํƒ€๋‹นํ•ฉ๋‹ˆ๋‹ค. 1.3.2.1. ๋งˆ์ฃผ์น  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์‹œ์ง€ ํƒ€์ž…์— ๋Œ€ํ•œ ์ •์˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‹คํ—˜์€ Lean์ด ์˜ค๋ฒ„๋กœ๋“œ๋œ ์ •์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด์„ ์ง€์›ํ•˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์— ๋” ๋ณต์žกํ•ด์ง‘๋‹ˆ๋‹ค. Nat์ด ๋„ˆ๋ฌด ์งง๋‹ค๋ฉด, ๋” ๊ธด ์ด๋ฆ„ NaturalNumber๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.def NaturalNumber : Type := Nat ๊ทธ๋Ÿฌ๋‚˜ Nat ๋Œ€์‹  NaturalNumber๋ฅผ ์ •์˜์˜ ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ๋‹ค์Œ ์ •์˜๋Š”:def thirtyEight : NaturalNumber := 38 ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. failed to synthesize OfNat NaturalNumber 38numerals are polymorphic in Lean, but the numeral `38` cannot be used in a context where the expected type is NaturalNumberdue to the absence of the instance aboveHint: Additional diagnostic information may be available using the `set_option diagnostics true` command. ์ด ์˜ค๋ฅ˜๋Š” Lean์ด ์ˆซ์ž ๋ฆฌํ„ฐ๋Ÿด์„ ์˜ค๋ฒ„๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํƒ€๋‹นํ•  ๊ฒฝ์šฐ, ์ž์—ฐ์ˆ˜ ๋ฆฌํ„ฐ๋Ÿด์€ ๋งˆ์น˜ ํ•ด๋‹น ํƒ€์ž…์ด ์‹œ์Šคํ…œ์— ๋‚ด์žฅ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์ƒˆ๋กœ์šด ํƒ€์ž…์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ˆ˜ํ•™์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋ ค๋Š” Lean์˜ ๋ชฉํ‘œ์˜ ์ผ๋ถ€์ด๋ฉฐ, ์ˆ˜ํ•™์˜ ๋‹ค๋ฅธ ๋ถ„์•ผ์—์„œ๋Š” ์ˆซ์ž ํ‘œ๊ธฐ๋ฒ•์„ ๋งค์šฐ ๋‹ค๋ฅธ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ค๋ฒ„๋กœ๋”ฉ์„ ํ—ˆ์šฉํ•˜๋Š” ํŠน์ • ๊ธฐ๋Šฅ์€ ์˜ค๋ฒ„๋กœ๋”ฉ์„ ์ฐพ๊ธฐ ์ „์— ๋ชจ๋“  ์ •์˜๋œ ์ด๋ฆ„์„ ๊ทธ ์ •์˜๋กœ ๋Œ€์ฒดํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์ œํ•œ์„ ํ•ด๊ฒฐํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์ •์˜์˜ ์˜ค๋ฅธ์ชฝ์— Nat ํƒ€์ž…์„ ์ œ๊ณตํ•˜์—ฌ 38์— ๋Œ€ํ•ด Nat์˜ ์˜ค๋ฒ„๋กœ๋”ฉ ๊ทœ์น™์ด ์‚ฌ์šฉ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. def thirtyEight : NaturalNumber := (38 : Nat) NaturalNumber๋Š” ์ •์˜์— ๋”ฐ๋ผ Nat์™€ ๋™์ผํ•œ ํƒ€์ž…์ด๋ฏ€๋กœ ์ด ์ •์˜๋Š” ์—ฌ์ „ํžˆ ํƒ€์ž…์ด ์˜ฌ๋ฐ”๋ฆ…๋‹ˆ๋‹ค! ๋˜ ๋‹ค๋ฅธ ํ•ด๊ฒฐ์ฑ…์€ Nat์— ๋Œ€ํ•œ ์˜ค๋ฒ„๋กœ๋”ฉ๊ณผ ๋™๋“ฑํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” NaturalNumber์— ๋Œ€ํ•œ ์˜ค๋ฒ„๋กœ๋”ฉ์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” Lean์˜ ๋” ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, def ๋Œ€์‹  abbrev๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Nat์— ๋Œ€ํ•œ ์ƒˆ ์ด๋ฆ„์„ ์ •์˜ํ•˜๋ฉด ์˜ค๋ฒ„๋กœ๋”ฉ ํ•ด๊ฒฐ ๊ณผ์ •์—์„œ ์ •์˜๋œ ์ด๋ฆ„์ด ๊ทธ ์ •์˜๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. abbrev๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋œ ์ •์˜๋Š” ํ•ญ์ƒ ์ „๊ฐœ(unfold)๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ์€ ๋ฌธ์ œ์—†์ด ๋ฐ›์•„๋“ค์—ฌ์ง‘๋‹ˆ๋‹ค. abbrev N : Type := Natdef thirtyNine : N := 39 ๋‚ด๋ถ€์ ์œผ๋กœ ์ผ๋ถ€ ์ •์˜๋Š” ์˜ค๋ฒ„๋กœ๋”ฉ ํ•ด๊ฒฐ ์ค‘์— ์ „๊ฐœ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ‘œ์‹œ๋˜๋Š” ๋ฐ˜๋ฉด, ๋‹ค๋ฅธ ์ •์˜๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ „๊ฐœ๋  ์ •์˜๋ฅผ ์ถ•์•ฝ ๊ฐ€๋Šฅ(reducible)ํ•˜๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ถ•์•ฝ ๊ฐ€๋Šฅ์„ฑ์— ๋Œ€ํ•œ ์ œ์–ด๋Š” Lean์ด ํ™•์žฅ์„ฑ์„ ๊ฐ–์ถ”๊ธฐ ์œ„ํ•ด ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ์ •์˜๋ฅผ ์™„์ „ํžˆ ์ „๊ฐœํ•˜๋ฉด ๊ธฐ๊ณ„๊ฐ€ ์ฒ˜๋ฆฌํ•˜๊ธฐ์— ๋А๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ๋งค์šฐ ํฐ ํƒ€์ž…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. abbrev๋กœ ์ƒ์„ฑ๋œ ์ •์˜๋Š” ์ถ•์•ฝ ๊ฐ€๋Šฅ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. 1.4. ๊ตฌ์กฐ์ฒด ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜๋Š” ์ฒซ ๋‹จ๊ณ„๋Š” ๋ณดํ†ต ๋ฌธ์ œ ์˜์—ญ์˜ ๊ฐœ๋…์„ ํŒŒ์•…ํ•œ ๋‹ค์Œ, ์ฝ”๋“œ์—์„œ ์ด๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ๋„๋ฉ”์ธ ๊ฐœ๋…์ด ๋‹ค๋ฅธ ๋” ๊ฐ„๋‹จํ•œ ๊ฐœ๋…๋“ค์˜ ์ง‘ํ•ฉ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ์ด๋Ÿฌํ•œ ๋” ๊ฐ„๋‹จํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋“ค์„ ํ•˜๋‚˜์˜ "ํŒจํ‚ค์ง€"๋กœ ๋ฌถ์–ด ์˜๋ฏธ ์žˆ๋Š” ์ด๋ฆ„์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lean์—์„œ๋Š” ์ด๋ฅผ ๊ตฌ์กฐ์ฒด(structure)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ์ด๋Š” C๋‚˜ Rust์˜ struct, C#์˜ record์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•˜๋ฉด Lean์— ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ํƒ€์ž…์ด ๋„์ž…๋˜๋ฉฐ, ์ด ํƒ€์ž…์€ ๋‹ค๋ฅธ ์–ด๋–ค ํƒ€์ž…์œผ๋กœ๋„ ํ™˜์›๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์—ฌ๋Ÿฌ ๊ตฌ์กฐ์ฒด๊ฐ€ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋”๋ผ๋„ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐœ๋…์„ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ•œ ์ ์€ ์ง๊ต์ขŒํ‘œ๊ณ„๋‚˜ ๊ทน์ขŒํ‘œ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ์€ ํ•œ ์Œ์˜ ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•˜๋ฉด API ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•˜๋‚˜๋ฅผ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ํ˜ผ๋™ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lean์˜ ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž ํƒ€์ž…์€ Float์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž๋Š” ์ผ๋ฐ˜์ ์ธ ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. #check 1.21.2 : Float#check -454.2123215-454.2123215 : Float#check 0.00.0 : Float ๋ถ€๋™์†Œ์ˆ˜์  ์ˆซ์ž๋ฅผ ์†Œ์ˆ˜์ ๊ณผ ํ•จ๊ป˜ ์ž‘์„ฑํ•˜๋ฉด Lean์€ Float ํƒ€์ž…์„ ์ถ”๋ก ํ•ฉ๋‹ˆ๋‹ค. ์†Œ์ˆ˜์  ์—†์ด ์ž‘์„ฑํ•˜๋ฉด ํƒ€์ž… ๋ช…์‹œ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #check 00 : Nat#check (0 : Float)0 : Float ์ง๊ต์ขŒํ‘œ๊ณ„์˜ ์ ์€ x์™€ y๋ผ๋Š” ๋‘ ๊ฐœ์˜ Float ํ•„๋“œ๋ฅผ ๊ฐ€์ง„ ๊ตฌ์กฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด๋Š” structure ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ ์–ธ๋ฉ๋‹ˆ๋‹ค. structure Point where x : Float y : Float ์ด ์„ ์–ธ ์ดํ›„, Point๋Š” ์ƒˆ๋กœ์šด ๊ตฌ์กฐ์ฒด ํƒ€์ž…์ด ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด ํƒ€์ž…์˜ ๊ฐ’์„ ๋งŒ๋“œ๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ ์ค‘๊ด„ํ˜ธ ์•ˆ์— ๋ชจ๋“  ํ•„๋“œ์— ๋Œ€ํ•œ ๊ฐ’์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐ์นด๋ฅดํŠธ ํ‰๋ฉด์˜ ์›์ ์€ x์™€ y๊ฐ€ ๋ชจ๋‘ 0์ธ ๊ณณ์ž…๋‹ˆ๋‹ค. def origin : Point := { x := 0.0, y := 0.0 } #eval origin์˜ ๊ฒฐ๊ณผ๋Š” origin์˜ ์ •์˜์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค. { x := 0.000000, y := 0.000000 } ๊ตฌ์กฐ์ฒด๋Š” ๋ฐ์ดํ„ฐ ๋ชจ์Œ์„ "๋ฌถ์–ด์„œ" ์ด๋ฆ„์„ ๋ถ™์ด๊ณ  ๋‹จ์ผ ๋‹จ์œ„๋กœ ์ทจ๊ธ‰ํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•˜๋ฏ€๋กœ, ๊ตฌ์กฐ์ฒด์˜ ๊ฐœ๋ณ„ ํ•„๋“œ๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” C, Python, Rust ๋˜๋Š” JavaScript์—์„œ์ฒ˜๋Ÿผ ์  ํ‘œ๊ธฐ๋ฒ•(dot notation)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. #eval origin.x0.000000#eval origin.y0.000000 ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์กฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ ์˜ ๋ง์…ˆ์€ ๊ธฐ๋ณธ ์ขŒํ‘œ ๊ฐ’์„ ๋”ํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. #eval addPoints { x := 1.5, y := 32 } { x := -8, y := 0.2 } ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. { x := -6.500000, y := 32.200000 } ํ•จ์ˆ˜ ์ž์ฒด๋Š” p1๊ณผ p2๋ผ๋Š” ๋‘ ๊ฐœ์˜ Point๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ์ ์€ p1๊ณผ p2์˜ x ๋ฐ y ํ•„๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. def addPoints (p1 : Point) (p2 : Point) : Point := { x := p1.x + p2.x, y := p1.y + p2.y } ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋‘ ์  ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ, ์ฆ‰ x์™€ y ์„ฑ๋ถ„ ์ฐจ์ด์˜ ์ œ๊ณฑ์˜ ํ•ฉ์˜ ์ œ๊ณฑ๊ทผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def distance (p1 : Point) (p2 : Point) : Float := Float.sqrt (((p2.x - p1.x) ^ 2.0) + ((p2.y - p1.y) ^ 2.0)) ์˜ˆ๋ฅผ ๋“ค์–ด, (1,2)์™€ (5,โˆ’1) ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋Š” 5์ž…๋‹ˆ๋‹ค. #eval distance { x := 1.0, y := 2.0 } { x := 5.0, y := -1.0 }5.000000 ์—ฌ๋Ÿฌ ๊ตฌ์กฐ์ฒด๊ฐ€ ๊ฐ™์€ ์ด๋ฆ„์˜ ํ•„๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 3์ฐจ์› ์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ x์™€ y ํ•„๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ™์€ ํ•„๋“œ ์ด๋ฆ„์œผ๋กœ ์ธ์Šคํ„ด์Šคํ™”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. structure Point3D where x : Float y : Float z : Floatdef origin3D : Point3D := { x := 0.0, y := 0.0, z := 0.0 } ์ด๋Š” ์ค‘๊ด„ํ˜ธ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ์กฐ์ฒด์˜ ์˜ˆ์ƒ ํƒ€์ž…์„ ์•Œ์•„์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž…์„ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ Lean์€ ๊ตฌ์กฐ์ฒด๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ์ฝ”๋“œ๋Š”: #check { x := 0.0, y := 0.0 } ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. invalid {...} notation, expected type is not known ๋ณดํ†ต ๊ทธ๋ ‡๋“ฏ์ด, ํƒ€์ž… ๋ช…์‹œ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์ด ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #check ({ x := 0.0, y := 0.0 } : Point){ x := 0.0, y := 0.0 } : Point ํ”„๋กœ๊ทธ๋žจ์„ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด, Lean์€ ์ค‘๊ด„ํ˜ธ ์•ˆ์— ๊ตฌ์กฐ์ฒด ํƒ€์ž… ๋ช…์‹œ๋ฅผ ํ—ˆ์šฉํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. #check { x := 0.0, y := 0.0 : Point}{ x := 0.0, y := 0.0 } : Point 1.4.1. ๊ตฌ์กฐ์ฒด ์—…๋ฐ์ดํŠธ Point์˜ x ํ•„๋“œ๋ฅผ 0์œผ๋กœ ๋ฐ”๊พธ๋Š” zeroX๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ด ๋ฌธ์žฅ์€ x๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฉ”๋ชจ๋ฆฌ ์œ„์น˜๋ฅผ ์ƒˆ ๊ฐ’์œผ๋กœ ๋ฎ์–ด์จ์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Lean์€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์ง„์ˆ ์€ ๊ฑฐ์˜ ํ•ญ์ƒ x ํ•„๋“œ๋Š” ์ƒˆ ๊ฐ’์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“  ํ•„๋“œ๋Š” ์ž…๋ ฅ์˜ ์›๋ž˜ ๊ฐ’์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ƒˆ๋กœ์šด Point๊ฐ€ ํ• ๋‹น๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. zeroX๋ฅผ ์ž‘์„ฑํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์ด ์„ค๋ช…์„ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ๋”ฐ๋ผ, x์— ๋Œ€ํ•œ ์ƒˆ ๊ฐ’์„ ์ฑ„์šฐ๊ณ  y๋ฅผ ์ˆ˜๋™์œผ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. def zeroX (p : Point) : Point := { x := 0, y := p.y } ๊ทธ๋Ÿฌ๋‚˜ ์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ์—๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ์งธ, ๊ตฌ์กฐ์ฒด์— ์ƒˆ ํ•„๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ์–ด๋–ค ํ•„๋“œ๋“  ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ชจ๋“  ๊ณณ์„ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค. ๋‘˜์งธ, ๊ตฌ์กฐ์ฒด์— ๊ฐ™์€ ํƒ€์ž…์˜ ํ•„๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ํฌํ•จ๋œ ๊ฒฝ์šฐ, ๋ณต์‚ฌ-๋ถ™์—ฌ๋„ฃ๊ธฐ ์ฝ”๋”ฉ์œผ๋กœ ์ธํ•ด ํ•„๋“œ ๋‚ด์šฉ์ด ์ค‘๋ณต๋˜๊ฑฐ๋‚˜ ๋ฐ”๋€Œ๋Š” ์‹ค์ œ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ํ”„๋กœ๊ทธ๋žจ์ด ๊ธธ๊ณ  ๊ด€๋ฃŒ์ ์œผ๋กœ ๋ณ€ํ•ฉ๋‹ˆ๋‹ค. Lean์€ ๊ตฌ์กฐ์ฒด์˜ ์ผ๋ถ€ ํ•„๋“œ๋Š” ๋ฐ”๊พธ๊ณ  ๋‚˜๋จธ์ง€๋Š” ๊ทธ๋Œ€๋กœ ๋‘๋Š” ํŽธ๋ฆฌํ•œ ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ตฌ์กฐ์ฒด ์ดˆ๊ธฐํ™”์—์„œ with ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ํ•„๋“œ์˜ ์†Œ์Šค๋Š” with ์•ž์— ์˜ค๊ณ , ์ƒˆ ํ•„๋“œ๋Š” ๋’ค์— ์˜ต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, zeroX๋Š” ์ƒˆ๋กœ์šด x ๊ฐ’๋งŒ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def zeroX (p : Point) : Point := { p with x := 0 } ์ด ๊ตฌ์กฐ์ฒด ์—…๋ฐ์ดํŠธ ๊ตฌ๋ฌธ์€ ๊ธฐ์กด ๊ฐ’์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ , ์ด์ „ ๊ฐ’๊ณผ ์ผ๋ถ€ ํ•„๋“œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ์ƒˆ ๊ฐ’์„ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. fourAndThree๋ผ๋Š” ์ ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ: def fourAndThree : Point := { x := 4.3, y := 3.4 } ์ด๋ฅผ ํ‰๊ฐ€ํ•œ ๋‹ค์Œ, zeroX๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—…๋ฐ์ดํŠธํ•œ ๊ฒƒ์„ ํ‰๊ฐ€ํ•˜๊ณ , ๋‹ค์‹œ ํ‰๊ฐ€ํ•˜๋ฉด ์›๋ž˜ ๊ฐ’์ด ๋‚˜์˜ต๋‹ˆ๋‹ค. #eval fourAndThree{ x := 4.300000, y := 3.400000 }#eval zeroX fourAndThree{ x := 0.000000, y := 3.400000 }#eval fourAndThree{ x := 4.300000, y := 3.400000 } ๊ตฌ์กฐ์ฒด ์—…๋ฐ์ดํŠธ๊ฐ€ ์›๋ณธ ๊ตฌ์กฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์˜ ํ•œ ๊ฐ€์ง€ ๊ฒฐ๊ณผ๋Š”, ์ƒˆ ๊ฐ’์ด ์ด์ „ ๊ฐ’์œผ๋กœ๋ถ€ํ„ฐ ๊ณ„์‚ฐ๋˜๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ์ถ”๋ก ํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฌ์›Œ์ง„๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ „ ๊ตฌ์กฐ์ฒด์— ๋Œ€ํ•œ ๋ชจ๋“  ์ฐธ์กฐ๋Š” ์ œ๊ณต๋œ ๋ชจ๋“  ์ƒˆ ๊ฐ’์—์„œ ๊ณ„์† ๋™์ผํ•œ ํ•„๋“œ ๊ฐ’์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. 1.4.2. ๋‚ด๋ถ€ ๋™์ž‘ ๋ชจ๋“  ๊ตฌ์กฐ์ฒด์—๋Š” ์ƒ์„ฑ์ž(constructor)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ "์ƒ์„ฑ์ž"๋ผ๋Š” ์šฉ์–ด๋Š” ํ˜ผ๋ž€์˜ ์›์ธ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Java๋‚˜ Python๊ณผ ๊ฐ™์€ ์–ธ์–ด์˜ ์ƒ์„ฑ์ž์™€ ๋‹ฌ๋ฆฌ, Lean์˜ ์ƒ์„ฑ์ž๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ์ดˆ๊ธฐํ™”๋  ๋•Œ ์‹คํ–‰๋˜๋Š” ์ž„์˜์˜ ์ฝ”๋“œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๋Œ€์‹ , ์ƒ์„ฑ์ž๋Š” ์ƒˆ๋กœ ํ• ๋‹น๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์— ์ €์žฅ๋  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹จ์ˆœํžˆ ๋ชจ์œผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์ „์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ์ธ์ˆ˜๋ฅผ ๊ฑฐ๋ถ€ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ƒ์„ฑ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” "์ƒ์„ฑ์ž"๋ผ๋Š” ๋‹จ์–ด๊ฐ€ ๋‘ ๋งฅ๋ฝ์—์„œ ์„œ๋กœ ๊ด€๋ จ์€ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, S๋ผ๋Š” ์ด๋ฆ„์˜ ๊ตฌ์กฐ์ฒด์— ๋Œ€ํ•œ ์ƒ์„ฑ์ž๋Š” S.mk๋ผ๋Š” ์ด๋ฆ„์ด ๋ถ™์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ S๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค ํ•œ์ •์ž์ด๊ณ , mk๋Š” ์ƒ์„ฑ์ž ์ž์ฒด์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์ค‘๊ด„ํ˜ธ ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ ๋Œ€์‹  ์ƒ์„ฑ์ž๋ฅผ ์ง์ ‘ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. #check Point.mk 1.5 2.8 ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ข‹์€ Lean ์Šคํƒ€์ผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์œผ๋ฉฐ, Lean์กฐ์ฐจ๋„ ํ‘œ์ค€ ๊ตฌ์กฐ์ฒด ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. { x := 1.5, y := 2.8 } : Point ์ƒ์„ฑ์ž๋Š” ํ•จ์ˆ˜ ํƒ€์ž…์„ ๊ฐ€์ง€๋ฏ€๋กœ, ํ•จ์ˆ˜๊ฐ€ ์˜ˆ์ƒ๋˜๋Š” ๋ชจ๋“  ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Point.mk๋Š” ๋‘ ๊ฐœ์˜ Float(๊ฐ๊ฐ x์™€ y)๋ฅผ ๋ฐ›์•„ ์ƒˆ๋กœ์šด Point๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. #check (Point.mk)Point.mk : Float โ†’ Float โ†’ Point ๊ตฌ์กฐ์ฒด์˜ ์ƒ์„ฑ์ž ์ด๋ฆ„์„ ์žฌ์ •์˜ํ•˜๋ ค๋ฉด, ์ด๋ฆ„ ์•ž์— ์ฝœ๋ก  ๋‘ ๊ฐœ๋ฅผ ๋ถ™์—ฌ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Point.mk ๋Œ€์‹  Point.point๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. structure Point where point :: x : Float y : Float ์ƒ์„ฑ์ž ์™ธ์—๋„, ๊ตฌ์กฐ์ฒด์˜ ๊ฐ ํ•„๋“œ์— ๋Œ€ํ•ด ์ ‘๊ทผ์ž(accessor) ํ•จ์ˆ˜๊ฐ€ ์ •์˜๋ฉ๋‹ˆ๋‹ค. ์ด๋“ค์€ ๊ตฌ์กฐ์ฒด์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋‚ด์—์„œ ํ•„๋“œ์™€ ๋™์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. Point์˜ ๊ฒฝ์šฐ, ์ ‘๊ทผ์ž ํ•จ์ˆ˜ Point.x์™€ Point.y๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. #check (Point.x)Point.x : Point โ†’ Float#check (Point.y)Point.y : Point โ†’ Float ์‚ฌ์‹ค, ์ค‘๊ด„ํ˜ธ ๊ตฌ์กฐ์ฒด ์ƒ์„ฑ ๊ตฌ๋ฌธ์ด ๋‚ด๋ถ€์ ์œผ๋กœ ๊ตฌ์กฐ์ฒด์˜ ์ƒ์„ฑ์ž ํ˜ธ์ถœ๋กœ ๋ณ€ํ™˜๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ด์ „ addPoints ์ •์˜์˜ x ๊ตฌ๋ฌธ์€ x ์ ‘๊ทผ์ž ํ˜ธ์ถœ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, #eval origin.x์™€ #eval Point.x origin์€ ๋ชจ๋‘ ๋‹ค์Œ์„ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. 0.000000 ์ ‘๊ทผ์ž ์  ํ‘œ๊ธฐ๋ฒ•์€ ๊ตฌ์กฐ์ฒด ํ•„๋“œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋” ๋งŽ์€ ๊ฒƒ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž„์˜์˜ ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ์ผ๋ฐ˜์ ์œผ๋กœ, ์ ‘๊ทผ์ž ํ‘œ๊ธฐ๋ฒ•์€ TARGET.f ARG1 ARG2 ... ํ˜•์‹์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. TARGET์˜ ํƒ€์ž…์ด T์ด๋ฉด, T.f๋ผ๋Š” ์ด๋ฆ„์˜ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. TARGET์€ ํƒ€์ž…์ด T์ธ ๊ฐ€์žฅ ์™ผ์ชฝ ์ธ์ˆ˜๊ฐ€ ๋˜๋ฉฐ(ํ•ญ์ƒ ์ฒซ ๋ฒˆ์งธ๋Š” ์•„๋‹˜), ARG1 ARG2 ...๋Š” ๋‚˜๋จธ์ง€ ์ธ์ˆ˜๋กœ ์ˆœ์„œ๋Œ€๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, String์€ append ํ•„๋“œ๋ฅผ ๊ฐ€์ง„ ๊ตฌ์กฐ์ฒด๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ, ์ ‘๊ทผ์ž ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ๋ฌธ์ž์—ด์—์„œ String.append๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #eval "one string".append " and another""one string and another" ์ด ์˜ˆ์—์„œ TARGET์€ "one string"์„ ๋‚˜ํƒ€๋‚ด๊ณ  ARG1์€ " and another"๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. Point.modifyBoth ํ•จ์ˆ˜(์ฆ‰, Point ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ •์˜๋œ modifyBoth)๋Š” Point์˜ ๋‘ ํ•„๋“œ ๋ชจ๋‘์— ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. def Point.modifyBoth (f : Float โ†’ Float) (p : Point) : Point := { x := f p.x, y := f p.y } Point ์ธ์ˆ˜๊ฐ€ ํ•จ์ˆ˜ ์ธ์ˆ˜ ๋’ค์— ์˜ค๋”๋ผ๋„, ์  ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #eval fourAndThree.modifyBoth Float.floor{ x := 4.000000, y := 3.000000 } ์ด ๊ฒฝ์šฐ, TARGET์€ fourAndThree๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , ARG1์€ Float.floor์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ ‘๊ทผ์ž ํ‘œ๊ธฐ๋ฒ•์˜ ๋Œ€์ƒ์ด ๋ฐ˜๋“œ์‹œ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ, ํƒ€์ž…์ด ์ผ์น˜ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 1.4.3. ์—ฐ์Šต ๋ฌธ์ œ ์ง์œก๋ฉด์ฒด์˜ ๋†’์ด, ๋„ˆ๋น„, ๊นŠ์ด๋ฅผ ๊ฐ๊ฐ Float์œผ๋กœ ํฌํ•จํ•˜๋Š” RectangularPrism์ด๋ผ๋Š” ์ด๋ฆ„์˜ ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•˜์„ธ์š”. ์ง์œก๋ฉด์ฒด์˜ ๋ถ€ํ”ผ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” volume : RectangularPrism โ†’ Float๋ผ๋Š” ์ด๋ฆ„์˜ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์„ธ์š”. ๋์ ์œผ๋กœ ์„ ๋ถ„์„ ๋‚˜ํƒ€๋‚ด๋Š” Segment๋ผ๋Š” ์ด๋ฆ„์˜ ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•˜๊ณ , ์„ ๋ถ„์˜ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” length : Segment โ†’ Float๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์„ธ์š”. Segment๋Š” ์ตœ๋Œ€ ๋‘ ๊ฐœ์˜ ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. RectangularPrism์˜ ์„ ์–ธ์œผ๋กœ ์–ด๋–ค ์ด๋ฆ„๋“ค์ด ๋„์ž…๋˜๋‚˜์š”? ๋‹ค์Œ Hamster์™€ Book ์„ ์–ธ์œผ๋กœ ์–ด๋–ค ์ด๋ฆ„๋“ค์ด ๋„์ž…๋˜๋‚˜์š”? ๊ทธ๋“ค์˜ ํƒ€์ž…์€ ๋ฌด์—‡์ธ๊ฐ€์š”? structure Hamster where name : String fluffy : Boolstructure Book where makeBook :: title : String author : String price : Float 1.5. ์ž๋ฃŒํ˜•๊ณผ ํŒจํ„ด ๊ตฌ์กฐ์ฒด๋Š” ์—ฌ๋Ÿฌ ๋…๋ฆฝ์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ํƒ€์ž…์œผ๋กœ ํ‘œํ˜„๋˜๋Š” ์ผ๊ด€๋œ ์ „์ฒด๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด์ฒ˜๋Ÿผ ๊ฐ’์˜ ๋ชจ์Œ์„ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ํƒ€์ž…์„ ๊ณฑ ํƒ€์ž…(product type)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋งŽ์€ ๋„๋ฉ”์ธ ๊ฐœ๋…์€ ๊ตฌ์กฐ์ฒด๋กœ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ‘œํ˜„๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์–ด๋–ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์‚ฌ์šฉ์ž ๊ถŒํ•œ์„ ์ถ”์ ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ผ๋ถ€ ์‚ฌ์šฉ์ž๋Š” ๋ฌธ์„œ ์†Œ์œ ์ž์ด๊ณ , ์ผ๋ถ€๋Š” ๋ฌธ์„œ๋ฅผ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ„์‚ฐ๊ธฐ์—๋Š” ๋ง์…ˆ, ๋บ„์…ˆ, ๊ณฑ์…ˆ๊ณผ ๊ฐ™์€ ์—ฌ๋Ÿฌ ์ดํ•ญ ์—ฐ์‚ฐ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด๋Š” ์—ฌ๋Ÿฌ ์„ ํƒ์ง€๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๋Š” ์‰ฌ์šด ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ตฌ์กฐ์ฒด๋Š” ๊ณ ์ •๋œ ์ˆ˜์˜ ํ•„๋“œ๋ฅผ ์ถ”์ ํ•˜๋Š” ํ›Œ๋ฅญํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ, ๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ž„์˜์˜ ์ˆ˜์˜ ์š”์†Œ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํŠธ๋ฆฌ๋‚˜ ๋ฆฌ์ŠคํŠธ์™€ ๊ฐ™์€ ๋Œ€๋ถ€๋ถ„์˜ ๊ณ ์ „์ ์ธ ์ž๋ฃŒ ๊ตฌ์กฐ๋Š” ์žฌ๊ท€์ ์ธ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์˜ ๊ผฌ๋ฆฌ๊ฐ€ ๊ทธ ์ž์ฒด๋กœ ๋ฆฌ์ŠคํŠธ์ด๊ฑฐ๋‚˜, ์ด์ง„ ํŠธ๋ฆฌ์˜ ์™ผ์ชฝ๊ณผ ์˜ค๋ฅธ์ชฝ ๊ฐ€์ง€๊ฐ€ ๊ทธ ์ž์ฒด๋กœ ์ด์ง„ ํŠธ๋ฆฌ์ธ ๊ฒฝ์šฐ์ฒ˜๋Ÿผ ๋ง์ž…๋‹ˆ๋‹ค. ์•ž์„œ ์–ธ๊ธ‰ํ•œ ๊ณ„์‚ฐ๊ธฐ์—์„œ ํ‘œํ˜„์‹ ์ž์ฒด์˜ ๊ตฌ์กฐ๊ฐ€ ์žฌ๊ท€์ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ง์…ˆ ํ‘œํ˜„์‹์˜ ํ”ผ๊ฐ€์‚ฐ์ˆ˜๋Š” ๊ทธ ์ž์ฒด๊ฐ€ ๊ณฑ์…ˆ ํ‘œํ˜„์‹์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒ์„ ํ—ˆ์šฉํ•˜๋Š” ์ž๋ฃŒํ˜•์„ ํ•ฉ ํƒ€์ž…(sum type)์ด๋ผ๊ณ  ํ•˜๊ณ , ์ž๊ธฐ ์ž์‹ ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒํ˜•์„ ์žฌ๊ท€ ์ž๋ฃŒํ˜•(recursive datatype)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์žฌ๊ท€์ ์ธ ํ•ฉ ํƒ€์ž…์€ ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•(inductive datatype)์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š”๋ฐ, ์ˆ˜ํ•™์  ๊ท€๋‚ฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์— ๋Œ€ํ•œ ๋ช…์ œ๋ฅผ ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•  ๋•Œ, ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์€ ํŒจํ„ด ๋งค์นญ๊ณผ ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ๋‚ด์žฅ ํƒ€์ž…์€ ์‚ฌ์‹ค ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์žˆ๋Š” ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Bool์€ ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์ž…๋‹ˆ๋‹ค. inductive Bool where | false : Bool | true : Bool ์ด ์ •์˜๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๋ถ€๋ถ„์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ค„์€ ์ƒˆ๋กœ์šด ํƒ€์ž…์˜ ์ด๋ฆ„(Bool)์„ ์ œ๊ณตํ•˜๊ณ , ๋‚˜๋จธ์ง€ ์ค„๋“ค์€ ๊ฐ๊ฐ ์ƒ์„ฑ์ž(constructor)๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด์˜ ์ƒ์„ฑ์ž์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์˜ ์ƒ์„ฑ์ž๋Š” ์ž„์˜์˜ ์ดˆ๊ธฐํ™” ๋ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๊ณณ์ด ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ๋‹ด๋Š” ๋‹จ์ˆœํ•˜๊ณ  ๋น„ํ™œ์„ฑ์ ์ธ ์ปจํ…Œ์ด๋„ˆ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด์™€ ๋‹ฌ๋ฆฌ, ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์€ ์—ฌ๋Ÿฌ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” true์™€ false๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ƒ์„ฑ์ž๊ฐ€ ์žˆ์œผ๋ฉฐ, ๋‘˜ ๋‹ค ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด ์„ ์–ธ์ด ์„ ์–ธ๋œ ํƒ€์ž…์˜ ์ด๋ฆ„์„ ๋”ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ž์‹ ์˜ ์ด๋ฆ„์„ ๋„ฃ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•๋„ ์ƒ์„ฑ์ž์˜ ์ด๋ฆ„์„ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋„ฃ์Šต๋‹ˆ๋‹ค. Lean ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” true์™€ false๊ฐ€ ์ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ๋‹ค์‹œ ์ต์ŠคํฌํŠธ๋˜์–ด Bool.true์™€ Bool.false๊ฐ€ ์•„๋‹Œ, ๋‹จ๋…์œผ๋กœ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง ๊ด€์ ์—์„œ, ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์€ ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ ๋ด‰์ธ๋œ ์ถ”์ƒ ํด๋ž˜์Šค(sealed abstract class)๊ฐ€ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ ๋งฅ๋ฝ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. C#์ด๋‚˜ Java์™€ ๊ฐ™์€ ์–ธ์–ด์—์„œ๋Š” Bool์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์œ ์‚ฌํ•˜๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. abstract class Bool {}class True extends Bool {}class False extends Bool {} ํ•˜์ง€๋งŒ, ์ด๋Ÿฌํ•œ ํ‘œํ˜„์˜ ๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ์€ ์ƒ๋‹นํžˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ํŠนํžˆ, ๊ฐ๊ฐ์˜ ๋น„์ถ”์ƒ ํด๋ž˜์Šค๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž…๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ํ• ๋‹นํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ๋ชจ๋‘ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ฐ์ฒด ์ง€ํ–ฅ ์˜ˆ์ œ์—์„œ True์™€ False๋Š” ๋ชจ๋‘ Bool๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์ธ ๋ฐ˜๋ฉด, Lean ์ •์˜๋Š” Bool์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž…๋งŒ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์Œ์ด ์•„๋‹Œ ์ •์ˆ˜ ํƒ€์ž…์ธ Nat์€ ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์ž…๋‹ˆ๋‹ค. inductive Nat where | zero : Nat | succ (n : Nat) : Nat ์—ฌ๊ธฐ์„œ zero๋Š” 0์„ ๋‚˜ํƒ€๋‚ด๊ณ , succ๋Š” ๋‹ค๋ฅธ ์–ด๋–ค ์ˆ˜์˜ ๋‹ค์Œ ์ˆ˜(successor)๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. succ์˜ ์„ ์–ธ์— ์–ธ๊ธ‰๋œ Nat์€ ๋ฐ”๋กœ ์ •์˜๋˜๊ณ  ์žˆ๋Š” Nat ํƒ€์ž… ๊ทธ ์ž์ฒด์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์ˆ˜๋ž€ "1 ๋” ํฐ ์ˆ˜"๋ฅผ ์˜๋ฏธํ•˜๋ฏ€๋กœ, 5์˜ ๋‹ค์Œ ์ˆ˜๋Š” 6์ด๊ณ  32,185์˜ ๋‹ค์Œ ์ˆ˜๋Š” 32,186์ž…๋‹ˆ๋‹ค. ์ด ์ •์˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, 4๋Š” Nat.succ (Nat.succ (Nat.succ (Nat.succ Nat.zero)))๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. ์ด ์ •์˜๋Š” ์ด๋ฆ„์ด ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๊ฒƒ์„ ์ œ์™ธํ•˜๋ฉด Bool์˜ ์ •์˜์™€ ๊ฑฐ์˜ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์œ ์ผํ•œ ์‹ค์งˆ์ ์ธ ์ฐจ์ด์ ์€ succ ๋’ค์— (n : Nat)๊ฐ€ ์˜จ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ, ์ด๋Š” succ ์ƒ์„ฑ์ž๊ฐ€ n์ด๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ Nat ํƒ€์ž…์˜ ์ธ์ž๋ฅผ ๋ฐ›๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. zero์™€ succ๋ผ๋Š” ์ด๋ฆ„์€ ๊ทธ๋“ค์˜ ํƒ€์ž…์„ ๋”ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ์œผ๋ฏ€๋กœ, ๊ฐ๊ฐ Nat.zero์™€ Nat.succ๋กœ ์ฐธ์กฐ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. n๊ณผ ๊ฐ™์€ ์ธ์ž ์ด๋ฆ„์€ Lean์˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋‚˜ ์ˆ˜ํ•™์  ์ฆ๋ช…์„ ์ž‘์„ฑํ•  ๋•Œ ์ œ๊ณต๋˜๋Š” ํ”ผ๋“œ๋ฐฑ์— ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lean์—๋Š” ์ด๋ฆ„์œผ๋กœ ์ธ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š” ์„ ํƒ์  ๊ตฌ๋ฌธ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ฐ˜์ ์œผ๋กœ ์ธ์ž ์ด๋ฆ„์˜ ์„ ํƒ์€ ๊ตฌ์กฐ์ฒด ํ•„๋“œ ์ด๋ฆ„์˜ ์„ ํƒ๋ณด๋‹ค ๋œ ์ค‘์š”ํ•œ๋ฐ, API์˜ ํฐ ๋ถ€๋ถ„์„ ์ฐจ์ง€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. C# ์ด๋‚˜ Java์—์„œ Nat์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. abstract class Nat {}class Zero extends Nat {}class Succ extends Nat { public Nat n; public Succ(Nat pred) { n = pred; }} ์œ„์˜ Bool ์˜ˆ์ œ์—์„œ์ฒ˜๋Ÿผ, ์ด๋Š” Lean์˜ ๋“ฑ๊ฐ€๋ฌผ๋ณด๋‹ค ๋” ๋งŽ์€ ํƒ€์ž…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ด ์˜ˆ์ œ๋Š” Lean ์ž๋ฃŒํ˜• ์ƒ์„ฑ์ž๊ฐ€ C# ์ด๋‚˜ Java์˜ ์ƒ์„ฑ์ž๋ผ๊ธฐ๋ณด๋‹ค๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์˜ ์„œ๋ธŒํด๋ž˜์Šค์™€ ํ›จ์”ฌ ๋” ์œ ์‚ฌํ•˜๋‹ค๋Š” ์ ์„ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋œ ์ƒ์„ฑ์ž๋Š” ์‹คํ–‰๋  ์ดˆ๊ธฐํ™” ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•ฉ ํƒ€์ž…์€ TypeScript์—์„œ ๊ตฌ๋ณ„๋œ ์œ ๋‹ˆ์˜จ(discriminated union)์„ ์ธ์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•ด ๋ฌธ์ž์—ด ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ๋„ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. TypeScript์—์„œ Nat์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. interface Zero { tag: "zero";}interface Succ { tag: "succ"; predecessor: Nat;}type Nat = Zero | Succ; C# ๋ฐ Java์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ด ์ธ์ฝ”๋”ฉ์€ Lean์—์„œ๋ณด๋‹ค ๋” ๋งŽ์€ ํƒ€์ž…์„ ๊ฐ€์ง€๊ฒŒ ๋˜๋Š”๋ฐ, Zero์™€ Succ๊ฐ€ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์ธ ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋Š” Lean ์ƒ์„ฑ์ž๊ฐ€ ๋‚ด์šฉ๋ฌผ์„ ์‹๋ณ„ํ•˜๋Š” ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•˜๋Š” JavaScript๋‚˜ TypeScript์˜ ๊ฐ์ฒด์— ํ•ด๋‹นํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. 1.5.1. ํŒจํ„ด ๋งค์นญ ๋งŽ์€ ์–ธ์–ด์—์„œ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๋Š” ๋จผ์ € ์ธ์Šคํ„ด์Šค-์˜ค๋ธŒ(instance-of) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ค ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๋ฐ›์•˜๋Š”์ง€ ํ™•์ธํ•œ ๋‹ค์Œ, ํ•ด๋‹น ์„œ๋ธŒํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ•„๋“œ์˜ ๊ฐ’์„ ์ฝ๋Š” ๋ฐฉ์‹์œผ๋กœ ์†Œ๋น„๋ฉ๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šค-์˜ค๋ธŒ ํ™•์ธ์€ ์–ด๋–ค ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ• ์ง€ ๊ฒฐ์ •ํ•˜์—ฌ ์ด ์ฝ”๋“œ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ณด์žฅํ•˜๋Š” ๋ฐ˜๋ฉด, ํ•„๋“œ ์ž์ฒด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Lean์—์„œ๋Š” ์ด ๋‘ ๊ฐ€์ง€ ๋ชฉ์ ์ด ๋ชจ๋‘ ํŒจํ„ด ๋งค์นญ์— ์˜ํ•ด ๋™์‹œ์— ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜์˜ ์˜ˆ๋Š” isZero๋กœ, ์ด ํ•จ์ˆ˜๋Š” ์ธ์ž๊ฐ€ Nat.zero์ผ ๋•Œ true๋ฅผ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. def isZero (n : Nat) : Bool := match n with | Nat.zero => true | Nat.succ k => false match ํ‘œํ˜„์‹์—๋Š” ํ•จ์ˆ˜์˜ ์ธ์ž n์ด ๊ตฌ์กฐ ๋ถ„ํ•ด๋ฅผ ์œ„ํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ n์ด Nat.zero์— ์˜ํ•ด ์ƒ์„ฑ๋˜์—ˆ๋‹ค๋ฉด, ํŒจํ„ด ๋งค์นญ์˜ ์ฒซ ๋ฒˆ์งธ ๋ถ„๊ธฐ๊ฐ€ ์„ ํƒ๋˜์–ด ๊ฒฐ๊ณผ๋Š” true๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ n์ด Nat.succ์— ์˜ํ•ด ์ƒ์„ฑ๋˜์—ˆ๋‹ค๋ฉด, ๋‘ ๋ฒˆ์งธ ๋ถ„๊ธฐ๊ฐ€ ์„ ํƒ๋˜์–ด ๊ฒฐ๊ณผ๋Š” false๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๋‹จ๊ณ„๋ณ„๋กœ, isZero Nat.zero์˜ ํ‰๊ฐ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. isZero Nat.zero โ€…โ€ŠโŸนโ€…โ€Š\implies match Nat.zero with โ€…โ€ŠโŸนโ€…โ€Š\implies | Nat.zero => true โ€…โ€ŠโŸนโ€…โ€Š\implies | Nat.succ k => false โ€…โ€ŠโŸนโ€…โ€Š\implies true isZero 5์˜ ํ‰๊ฐ€๋„ ๋น„์Šทํ•˜๊ฒŒ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. isZero 5 โ€…โ€ŠโŸนโ€…โ€Š\implies isZero (Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ Nat.zero))))) โ€…โ€ŠโŸนโ€…โ€Š\implies match Nat.succ (Nat.succ (Nat.succ (Nat.succ (Nat.succ Nat.zero)))) with| Nat.zero => true| Nat.succ k => false โ€…โ€ŠโŸนโ€…โ€Š\implies false isZero์˜ ํŒจํ„ด ๋‘ ๋ฒˆ์งธ ๋ถ„๊ธฐ์— ์žˆ๋Š” k๋Š” ์žฅ์‹์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋Š” Nat.succ์˜ ์ธ์ž์ธ Nat์„ ์ œ๊ณต๋œ ์ด๋ฆ„์œผ๋กœ ๋ณด์ด๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ทธ ๋” ์ž‘์€ ์ˆซ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„์‹์˜ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์ˆซ์ž n์˜ ๋‹ค์Œ ์ˆ˜๊ฐ€ n๋ณด๋‹ค 1 ํฐ ์ˆ˜(์ฆ‰, n+1)์ธ ๊ฒƒ์ฒ˜๋Ÿผ, ์–ด๋–ค ์ˆ˜์˜ ์ด์ „ ์ˆ˜(predecessor)๋Š” ๊ทธ ์ˆ˜๋ณด๋‹ค 1 ์ž‘์€ ์ˆ˜์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ pred๊ฐ€ Nat์˜ ์ด์ „ ์ˆ˜๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜๋ผ๋ฉด, ๋‹ค์Œ ์˜ˆ์ œ๋“ค์€ ์˜ˆ์ƒ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. #eval pred 54#eval pred 839838 Nat์€ ์Œ์ˆ˜๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, Nat.zero๋Š” ์•ฝ๊ฐ„์˜ ๋‚œ์ œ์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต Nat์œผ๋กœ ์ž‘์—…ํ•  ๋•Œ, ์Œ์ˆ˜๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์—ฐ์‚ฐ์ž๋“ค์€ 0 ์ž์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์žฌ์ •์˜๋ฉ๋‹ˆ๋‹ค. #eval pred 00 Nat์˜ ์ด์ „ ์ˆ˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด, ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ์–ด๋–ค ์ƒ์„ฑ์ž๊ฐ€ ๊ทธ๊ฒƒ์„ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ Nat.zero์˜€๋‹ค๋ฉด, ๊ฒฐ๊ณผ๋Š” Nat.zero์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ Nat.succ์˜€๋‹ค๋ฉด, k๋ผ๋Š” ์ด๋ฆ„์ด ๊ทธ ์•„๋ž˜์˜ Nat์„ ์ฐธ์กฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด Nat์ด ์›ํ•˜๋Š” ์ด์ „ ์ˆ˜์ด๋ฏ€๋กœ, Nat.succ ๋ถ„๊ธฐ์˜ ๊ฒฐ๊ณผ๋Š” k์ž…๋‹ˆ๋‹ค. def pred (n : Nat) : Nat := match n with | Nat.zero => Nat.zero | Nat.succ k => k ์ด ํ•จ์ˆ˜๋ฅผ 5์— ์ ์šฉํ•˜๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋“ค์ด ๋‚˜์˜ต๋‹ˆ๋‹ค. pred 5 โ€…โ€ŠโŸนโ€…โ€Š\implies pred (Nat.succ 4) โ€…โ€ŠโŸนโ€…โ€Š\implies match Nat.succ 4 with| Nat.zero => Nat.zero| Nat.succ k => k โ€…โ€ŠโŸนโ€…โ€Š\implies 4 ํŒจํ„ด ๋งค์นญ์€ ํ•ฉ ํƒ€์ž…๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ตฌ์กฐ์ฒด์™€๋„ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Point3D์—์„œ ์„ธ ๋ฒˆ์งธ ์ฐจ์›์„ ์ถ”์ถœํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def depth (p : Point3D) : Float := match p with | { x:= h, y := w, z := d } => d ์ด ๊ฒฝ์šฐ, Point3D.z ์ ‘๊ทผ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๊ฐ„๋‹จํ–ˆ๊ฒ ์ง€๋งŒ, ๊ตฌ์กฐ์ฒด ํŒจํ„ด์€ ๋•Œ๋•Œ๋กœ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1.5.2. ์žฌ๊ท€ ํ•จ์ˆ˜ ์ •์˜๋˜๊ณ  ์žˆ๋Š” ์ด๋ฆ„์„ ์ฐธ์กฐํ•˜๋Š” ์ •์˜๋ฅผ ์žฌ๊ท€ ์ •์˜(recursive definition)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•์€ ์žฌ๊ท€์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ, Nat์€ succ๊ฐ€ ๋˜ ๋‹ค๋ฅธ Nat์„ ์š”๊ตฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฌํ•œ ์ž๋ฃŒํ˜•์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค. ์žฌ๊ท€ ์ž๋ฃŒํ˜•์€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ฐ™์€ ๊ธฐ์ˆ ์  ์š”์ธ์— ์˜ํ•ด์„œ๋งŒ ์ œํ•œ๋˜๋Š”, ์ž„์˜๋กœ ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฃŒํ˜• ์ •์˜์—์„œ ๊ฐ ์ž์—ฐ์ˆ˜์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ์ƒ์„ฑ์ž๋ฅผ ๋ชจ๋‘ ์ ๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ฒ˜๋Ÿผ, ๊ฐ ๊ฐ€๋Šฅ์„ฑ์— ๋Œ€ํ•œ ํŒจํ„ด ๋งค์นญ ์ผ€์ด์Šค๋ฅผ ๋ชจ๋‘ ์ ๋Š” ๊ฒƒ๋„ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์žฌ๊ท€ ์ž๋ฃŒํ˜•์€ ์žฌ๊ท€ ํ•จ์ˆ˜์™€ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค. Nat์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์žฌ๊ท€ ํ•จ์ˆ˜๋Š” ์ธ์ž๊ฐ€ ์ง์ˆ˜์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, Nat.zero๋Š” ์ง์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ์ฝ”๋“œ์˜ ๋น„์žฌ๊ท€์ ์ธ ๋ถ„๊ธฐ๋ฅผ ๋ฒ ์ด์Šค ์ผ€์ด์Šค(base case)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ™€์ˆ˜์˜ ๋‹ค์Œ ์ˆ˜๋Š” ์ง์ˆ˜์ด๊ณ , ์ง์ˆ˜์˜ ๋‹ค์Œ ์ˆ˜๋Š” ํ™€์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด๋Š” Nat.succ๋กœ ๋งŒ๋“ค์–ด์ง„ ์ˆซ์ž๊ฐ€ ์ง์ˆ˜๋ผ๋Š” ๊ฒƒ์€ ๊ทธ ์ธ์ž๊ฐ€ ์ง์ˆ˜๊ฐ€ ์•„๋‹ ๋•Œ์™€ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. def even (n : Nat) : Bool := match n with | Nat.zero => true | Nat.succ k => not (even k) ์ด๋Ÿฌํ•œ ์‚ฌ๊ณ  ํŒจํ„ด์€ Nat์— ๋Œ€ํ•œ ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ „ํ˜•์ ์ž…๋‹ˆ๋‹ค. ๋จผ์ €, Nat.zero์— ๋Œ€ํ•ด ๋ฌด์—‡์„ ํ• ์ง€ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, ์ž„์˜์˜ Nat์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ ๋‹ค์Œ ์ˆ˜์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๊ณ , ์ด ๋ณ€ํ™˜์„ ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์„ ๊ตฌ์กฐ์  ์žฌ๊ท€(structural recursion)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ์–ธ์–ด์™€ ๋‹ฌ๋ฆฌ, Lean์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์žฌ๊ท€ ํ•จ์ˆ˜๊ฐ€ ๊ฒฐ๊ตญ ๋ฒ ์ด์Šค ์ผ€์ด์Šค์— ๋„๋‹ฌํ•˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€์ ์—์„œ ์ด๋Š” ์šฐ๋ฐœ์ ์ธ ๋ฌดํ•œ ๋ฃจํ”„๋ฅผ ๋ฐฐ์ œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๊ธฐ๋Šฅ์€ ์ •๋ฆฌ๋ฅผ ์ฆ๋ช…ํ•  ๋•Œ ํŠนํžˆ ์ค‘์š”ํ•œ๋ฐ, ๋ฌดํ•œ ๋ฃจํ”„๋Š” ํฐ ์–ด๋ ค์›€์„ ์•ผ๊ธฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•œ ๊ฒฐ๊ณผ ์ค‘ ํ•˜๋‚˜๋Š” Lean์ด ์›๋ž˜ ์ˆซ์ž์— ๋Œ€ํ•ด ์žฌ๊ท€์ ์œผ๋กœ ์ž์‹ ์„ ํ˜ธ์ถœํ•˜๋ ค๋Š” even ๋ฒ„์ „์„ ๋ฐ›์•„๋“ค์ด์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. def evenLoops (n : Nat) : Bool := match n with | Nat.zero => true | Nat.succ k => not (evenLoops n) ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์˜ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ Lean์ด ์žฌ๊ท€ ํ•จ์ˆ˜๊ฐ€ ํ•ญ์ƒ ๋ฒ ์ด์Šค ์ผ€์ด์Šค์— ๋„๋‹ฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(์‹ค์ œ๋กœ ๊ทธ๋ ‡์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค). fail to show termination for evenLoopswith errorsfailed to infer structural recursion:Not considering parameter n of evenLoops: it is unchanged in the recursive callsno parameters suitable for structural recursionwell-founded recursion cannot be used, `evenLoops` does not take any (non-fixed) arguments ๋ง์…ˆ์€ ๋‘ ๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›์ง€๋งŒ, ๊ทธ ์ค‘ ํ•˜๋‚˜๋งŒ ๊ฒ€์‚ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ˆซ์ž n์— 0์„ ๋”ํ•˜๋ ค๋ฉด, ๊ทธ๋ƒฅ n์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. k์˜ ๋‹ค์Œ ์ˆ˜๋ฅผ n์— ๋”ํ•˜๋ ค๋ฉด, k๋ฅผ n์— ๋”ํ•œ ๊ฒฐ๊ณผ์˜ ๋‹ค์Œ ์ˆ˜๋ฅผ ์ทจํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. def plus (n : Nat) (k : Nat) : Nat := match k with | Nat.zero => n | Nat.succ k' => Nat.succ (plus n k') plus์˜ ์ •์˜์—์„œ, k'๋ผ๋Š” ์ด๋ฆ„์€ ์ธ์ž k์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์ง€๋งŒ ๋™์ผํ•˜์ง€๋Š” ์•Š๋‹ค๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ์„ ํƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, plus 3 2์˜ ํ‰๊ฐ€๋ฅผ ๋”ฐ๋ผ๊ฐ€ ๋ณด๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋“ค์ด ๋‚˜์˜ต๋‹ˆ๋‹ค. plus 3 2 โ€…โ€ŠโŸนโ€…โ€Š\implies plus 3 (Nat.succ (Nat.succ Nat.zero)) โ€…โ€ŠโŸนโ€…โ€Š\implies match Nat.succ (Nat.succ Nat.zero) with| Nat.zero => 3| Nat.succ k' => Nat.succ (plus 3 k') โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (plus 3 (Nat.succ Nat.zero)) โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (match Nat.succ Nat.zero with| Nat.zero => 3| Nat.succ k' => Nat.succ (plus 3 k')) โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (Nat.succ (plus 3 Nat.zero)) โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (Nat.succ (match Nat.zero with| Nat.zero => 3| Nat.succ k' => Nat.succ (plus 3 k'))) โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (Nat.succ 3) โ€…โ€ŠโŸนโ€…โ€Š\implies 5 ๋ง์…ˆ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ n+kn+k๊ฐ€ Nat.succ๋ฅผ n์— k๋ฒˆ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด๋ผ๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋น„์Šทํ•˜๊ฒŒ, ๊ณฑ์…ˆ nร—kn\times k๋Š” n์„ ์ž์‹ ์—๊ฒŒ k๋ฒˆ ๋”ํ•˜๋Š” ๊ฒƒ์ด๊ณ , ๋บ„์…ˆ nโˆ’knโˆ’k๋Š” n์˜ ์ด์ „ ์ˆ˜๋ฅผ k๋ฒˆ ์ทจํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. def times (n : Nat) (k : Nat) : Nat := match k with | Nat.zero => Nat.zero | Nat.succ k' => plus n (times n k')def minus (n : Nat) (k : Nat) : Nat := match k with | Nat.zero => n | Nat.succ k' => pred (minus n k') ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ๊ตฌ์กฐ์  ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‰ฝ๊ฒŒ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ง์…ˆ์„ ๋ฐ˜๋ณต๋œ Nat.succ๋กœ, ๊ณฑ์…ˆ์„ ๋ฐ˜๋ณต๋œ ๋ง์…ˆ์œผ๋กœ, ๋บ„์…ˆ์„ ๋ฐ˜๋ณต๋œ ์ด์ „ ์ˆ˜๋กœ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ๋‚˜๋ˆ—์…ˆ์„ ๋ฐ˜๋ณต๋œ ๋บ„์…ˆ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ํ”ผ์ œ์ˆ˜๊ฐ€ ์ œ์ˆ˜๋ณด๋‹ค ์ž‘์œผ๋ฉด ๊ฒฐ๊ณผ๋Š” 0์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, ๊ฒฐ๊ณผ๋Š” ํ”ผ์ œ์ˆ˜์—์„œ ์ œ์ˆ˜๋ฅผ ๋บ€ ๊ฐ’์„ ์ œ์ˆ˜๋กœ ๋‚˜๋ˆˆ ๊ฐ’์˜ ๋‹ค์Œ ์ˆ˜์ž…๋‹ˆ๋‹ค. def div (n : Nat) (k : Nat) : Nat := if n < k then 0 else Nat.succ (div (n - k) k) ๋‘ ๋ฒˆ์งธ ์ธ์ž๊ฐ€ 0์ด ์•„๋‹Œ ํ•œ, ์ด ํ”„๋กœ๊ทธ๋žจ์€ ํ•ญ์ƒ ๋ฒ ์ด์Šค ์ผ€์ด์Šค๋ฅผ ํ–ฅํ•ด ์ง„ํ–‰ํ•˜๋ฏ€๋กœ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ๊ตฌ์กฐ์ ์œผ๋กœ ์žฌ๊ท€์ ์ด์ง€ ์•Š์€๋ฐ, 0์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ๊ณ  ๋” ์ž‘์€ Nat์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ ๋‹ค์Œ ์ˆ˜์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํŒจํ„ด์„ ๋”ฐ๋ฅด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ, ํ•จ์ˆ˜์˜ ์žฌ๊ท€์  ํ˜ธ์ถœ์ด ์ž…๋ ฅ ์ƒ์„ฑ์ž์˜ ์ธ์ž๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Lean์€ ๋‹ค์Œ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ์ด๋ฅผ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. fail to show termination for divwith errorsfailed to infer structural recursion:Not considering parameter k of div: it is unchanged in the recursive callsCannot use parameter k: failed to eliminate recursive application div (n - k) kfailed to prove termination, possible solutions: - Use `have`-expressions to prove the remaining goals - Use `termination_by` to specify a different well-founded relation - Use `decreasing_by` to specify your own tactic for discharging this kind of goalk n:Nathโœ:ยฌn < kโŠข n - k < n ์ด ๋ฉ”์‹œ์ง€๋Š” div๊ฐ€ ์ˆ˜๋™์œผ๋กœ ์ข…๋ฃŒ ์ฆ๋ช…์„ ์š”๊ตฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฃผ์ œ๋Š” ๋งˆ์ง€๋ง‰ ์žฅ์—์„œ ํƒ๊ตฌ๋ฉ๋‹ˆ๋‹ค. 1.6. ๋‹คํ˜•์„ฑ(Polymorphism) ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด์—์„œ์ฒ˜๋Ÿผ, Lean์—์„œ๋„ ํƒ€์ž…์€ ์ธ์ž๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, List Nat ํƒ€์ž…์€ ์ž์—ฐ์ˆ˜์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ, List String์€ ๋ฌธ์ž์—ด์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ, ๊ทธ๋ฆฌ๊ณ  List (List Point)๋Š” Point๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฆฌ์ŠคํŠธ๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด๋Š” C#์ด๋‚˜ Java ๊ฐ™์€ ์–ธ์–ด์˜ List<Nat>, List<String>, ๋˜๋Š” List<List<Point>>์™€ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. Lean์ด ํ•จ์ˆ˜์— ์ธ์ž๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ๊ณต๋ฐฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ํƒ€์ž…์— ์ธ์ž๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋„ ๊ณต๋ฐฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋‹คํ˜•์„ฑ์ด๋ผ๋Š” ์šฉ์–ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…๊ณผ ์ •์˜๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ์Šˆํผํด๋ž˜์Šค์˜ ์ผ๋ถ€ ๋™์ž‘์„ ์žฌ์ •์˜(override)ํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด ์ฑ…์—์„œ "๋‹คํ˜•์„ฑ"์€ ํ•ญ์ƒ ์ „์ž์˜ ์˜๋ฏธ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํƒ€์ž… ์ธ์ž๋“ค์€ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‚˜ ์ •์˜ ๋‚ด์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋™์ผํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด๋‚˜ ์ •์˜๋ฅผ ์ธ์ž์˜ ์ด๋ฆ„์„ ๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ์–ป์–ด์ง€๋Š” ๋ชจ๋“  ํƒ€์ž…๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Point ๊ตฌ์กฐ์ฒด๋Š” x์™€ y ํ•„๋“œ๊ฐ€ ๋ชจ๋‘ Float์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ ์— ๋Œ€ํ•ด ๊ฐ ์ขŒํ‘œ์— ํŠน์ • ํ‘œํ˜„์„ ์š”๊ตฌํ•˜๋Š” ๋ณธ์งˆ์ ์ธ ์ด์œ ๋Š” ์—†์Šต๋‹ˆ๋‹ค. Point์˜ ๋‹คํ˜•์  ๋ฒ„์ „์ธ PPoint๋Š” ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›์•„ ๋‘ ํ•„๋“œ์— ๋ชจ๋‘ ๊ทธ ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. structure PPoint (ฮฑ : Type) where x : ฮฑ y : ฮฑ ํ•จ์ˆ˜ ์ •์˜์˜ ์ธ์ž๋“ค์ด ์ •์˜๋˜๋Š” ์ด๋ฆ„ ๋ฐ”๋กœ ๋’ค์— ์“ฐ์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ๊ตฌ์กฐ์ฒด์˜ ์ธ์ž๋“ค๋„ ๊ตฌ์กฐ์ฒด ์ด๋ฆ„ ๋ฐ”๋กœ ๋’ค์— ์“ฐ์ž…๋‹ˆ๋‹ค. Lean์—์„œ๋Š” ๋” ๊ตฌ์ฒด์ ์ธ ์ด๋ฆ„์ด ๋– ์˜ค๋ฅด์ง€ ์•Š์„ ๋•Œ ํƒ€์ž… ์ธ์ž์˜ ์ด๋ฆ„์œผ๋กœ ๊ทธ๋ฆฌ์Šค ๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ด€๋ก€์ž…๋‹ˆ๋‹ค. Type์€ ๋‹ค๋ฅธ ํƒ€์ž…์„ ์„ค๋ช…ํ•˜๋Š” ํƒ€์ž…์ด๋ฏ€๋กœ, Nat, List String, PPoint Int๋Š” ๋ชจ๋‘ Type์ด๋ผ๋Š” ํƒ€์ž…์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. List์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, PPoint๋„ ํŠน์ • ํƒ€์ž…์„ ์ธ์ž๋กœ ์ œ๊ณตํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def natOrigin : PPoint Nat := { x := Nat.zero, y := Nat.zero } ์ด ์˜ˆ์ œ์—์„œ๋Š” ๋‘ ํ•„๋“œ ๋ชจ๋‘ Nat ํƒ€์ž…์ผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ์ธ์ž ๋ณ€์ˆ˜๋ฅผ ์ธ์ž ๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, PPoint์— Nat ํƒ€์ž…์„ ์ธ์ž๋กœ ์ œ๊ณตํ•˜๋ฉด x์™€ y ํ•„๋“œ๊ฐ€ Nat ํƒ€์ž…์„ ๊ฐ–๋Š” ๊ตฌ์กฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ธ์ž ์ด๋ฆ„ ฮฑ๊ฐ€ ์ธ์ž ํƒ€์ž… Nat์œผ๋กœ ๋Œ€์ฒด๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Lean์—์„œ ํƒ€์ž…์€ ์ผ๋ฐ˜์ ์ธ ํ‘œํ˜„์‹์ด๋ฏ€๋กœ, PPoint์™€ ๊ฐ™์€ ๋‹คํ˜•์  ํƒ€์ž…์— ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ํŠน๋ณ„ํ•œ ๋ฌธ๋ฒ•์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •์˜ ๋˜ํ•œ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋‹คํ˜•์ ์ด ๋ฉ๋‹ˆ๋‹ค. replaceX ํ•จ์ˆ˜๋Š” PPoint์˜ x ํ•„๋“œ๋ฅผ ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. replaceX๊ฐ€ ๋ชจ๋“  ๋‹คํ˜•์  Point์— ๋Œ€ํ•ด ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด, ํ•จ์ˆ˜ ์ž์ฒด๊ฐ€ ๋‹คํ˜•์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋ฅผ ์  ํ•„๋“œ์˜ ํƒ€์ž…์œผ๋กœ ํ•˜๊ณ , ์ดํ›„์˜ ์ธ์ž๋“ค์ด ์ฒซ ๋ฒˆ์งธ ์ธ์ž์˜ ์ด๋ฆ„์„ ์ฐธ์กฐํ•˜๋„๋ก ํ•จ์œผ๋กœ์จ ๋‹ฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. def replaceX (ฮฑ : Type) (point : PPoint ฮฑ) (newX : ฮฑ) : PPoint ฮฑ := { point with x := newX } ์ฆ‰, ์ธ์ž point์™€ newX์˜ ํƒ€์ž…์ด ฮฑ๋ฅผ ์–ธ๊ธ‰ํ•  ๋•Œ, ์ด๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ œ๊ณต๋œ ํƒ€์ž…์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํ•จ์ˆ˜ ์ธ์ž ์ด๋ฆ„์ด ํ•จ์ˆ˜ ๋ณธ๋ฌธ์—์„œ ์‚ฌ์šฉ๋  ๋•Œ ์ œ๊ณต๋œ ๊ฐ’์„ ์ฐธ์กฐํ•˜๋Š” ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Lean์—๊ฒŒ replaceX์˜ ํƒ€์ž…์„ ํ™•์ธํ•˜๋„๋ก ์š”์ฒญํ•œ ๋‹ค์Œ, replaceX Nat์˜ ํƒ€์ž…์„ ํ™•์ธํ•˜๋„๋ก ์š”์ฒญํ•จ์œผ๋กœ์จ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #check (replaceX)replaceX : (ฮฑ : Type) โ†’ PPoint ฮฑ โ†’ ฮฑ โ†’ PPoint ฮฑ ์ด ํ•จ์ˆ˜ ํƒ€์ž…์€ ์ฒซ ๋ฒˆ์งธ ์ธ์ž์˜ ์ด๋ฆ„์„ ํฌํ•จํ•˜๋ฉฐ, ํƒ€์ž… ๋‚ด์˜ ์ดํ›„ ์ธ์ž๋“ค์€ ์ด ์ด๋ฆ„์„ ๋‹ค์‹œ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ ์šฉ์˜ ๊ฐ’์ด ํ•จ์ˆ˜ ๋ณธ๋ฌธ์—์„œ ์ธ์ž ์ด๋ฆ„์„ ์ œ๊ณต๋œ ์ธ์ž ๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ์ฐพ์•„์ง€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ํ•จ์ˆ˜ ์ ์šฉ์˜ ํƒ€์ž…์€ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์—์„œ ์ธ์ž ์ด๋ฆ„์„ ์ œ๊ณต๋œ ๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ์ฐพ์•„์ง‘๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ž์ธ Nat์„ ์ œ๊ณตํ•˜๋ฉด, ํƒ€์ž…์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์— ์žˆ๋Š” ๋ชจ๋“  ฮฑ๊ฐ€ Nat์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. #check replaceX NatreplaceX Nat : PPoint Nat โ†’ Nat โ†’ PPoint Nat ๋‚˜๋จธ์ง€ ์ธ์ž๋“ค์€ ๋ช…์‹œ์ ์œผ๋กœ ์ด๋ฆ„์ด ์ง€์ •๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋” ๋งŽ์€ ์ธ์ž๊ฐ€ ์ œ๊ณต๋˜์–ด๋„ ์ถ”๊ฐ€์ ์ธ ์น˜ํ™˜์€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. #check replaceX Nat natOriginreplaceX Nat natOrigin : Nat โ†’ PPoint Nat#check replaceX Nat natOrigin 5replaceX Nat natOrigin 5 : PPoint Nat ์ „์ฒด ํ•จ์ˆ˜ ์ ์šฉ ํ‘œํ˜„์‹์˜ ํƒ€์ž…์ด ํƒ€์ž…์„ ์ธ์ž๋กœ ์ „๋‹ฌํ•จ์œผ๋กœ์จ ๊ฒฐ์ •๋˜์—ˆ๋‹ค๋Š” ์‚ฌ์‹ค์€ ๊ทธ๊ฒƒ์„ ํ‰๊ฐ€ํ•˜๋Š” ๋Šฅ๋ ฅ์— ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. #eval replaceX Nat natOrigin 5{ x := 5, y := 0 } ๋‹คํ˜•์  ํ•จ์ˆ˜๋Š” ์ด๋ฆ„์ด ์ง€์ •๋œ ํƒ€์ž… ์ธ์ž๋ฅผ ๋ฐ›๊ณ , ์ดํ›„์˜ ํƒ€์ž…๋“ค์ด ๊ทธ ์ธ์ž์˜ ์ด๋ฆ„์„ ์ฐธ์กฐํ•จ์œผ๋กœ์จ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํƒ€์ž… ์ธ์ž๋งŒ์ด ์ด๋ฆ„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ํŠน๋ณ„ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์–‘์ˆ˜ ๋˜๋Š” ์Œ์ˆ˜ ๋ถ€ํ˜ธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. inductive Sign where | pos | neg ์ธ์ž๊ฐ€ ๋ถ€ํ˜ธ์ธ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ์ž๊ฐ€ ์–‘์ˆ˜์ด๋ฉด ํ•จ์ˆ˜๋Š” Nat์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์Œ์ˆ˜์ด๋ฉด Int๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. def posOrNegThree (s : Sign) : match s with | Sign.pos => Nat | Sign.neg => Int := match s with | Sign.pos => (3 : Nat) | Sign.neg => (-3 : Int) ํƒ€์ž…์€ ์ผ๊ธ‰ ๊ฐ์ฒด์ด๋ฉฐ Lean ์–ธ์–ด์˜ ์ผ๋ฐ˜์ ์ธ ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ณ„์‚ฐ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ฐ์ดํ„ฐ ํƒ€์ž…์— ๋Œ€ํ•œ ํŒจํ„ด ๋งค์นญ์„ ํ†ตํ•ด ๊ณ„์‚ฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lean์ด ์ด ํ•จ์ˆ˜๋ฅผ ํ™•์ธํ•  ๋•Œ, ํ•จ์ˆ˜ ๋ณธ๋ฌธ์˜ match ํ‘œํ˜„์‹์ด ํƒ€์ž…์˜ match ํ‘œํ˜„์‹๊ณผ ์ผ์น˜ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ด์šฉํ•˜์—ฌ pos ์ผ€์ด์Šค์˜ ์˜ˆ์ƒ ํƒ€์ž…์„ Nat์œผ๋กœ, neg ์ผ€์ด์Šค์˜ ์˜ˆ์ƒ ํƒ€์ž…์„ Int๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. posOrNegThree๋ฅผ pos์— ์ ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ ๋ณธ๋ฌธ๊ณผ ๋ฐ˜ํ™˜ ํƒ€์ž… ๋ชจ๋‘์—์„œ ์ธ์ž ์ด๋ฆ„ s๊ฐ€ pos๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. ํ‰๊ฐ€๋Š” ํ‘œํ˜„์‹๊ณผ ๊ทธ ํƒ€์ž… ๋ชจ๋‘์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (posOrNegThree Sign.pos : match Sign.pos with | Sign.pos => Nat | Sign.neg => Int) โ€…โ€ŠโŸนโ€…โ€Š\implies ((match Sign.pos with | Sign.pos => (3 : Nat) | Sign.neg => (-3 : Int)) : match Sign.pos with | Sign.pos => Nat | Sign.neg => Int) โ€…โ€ŠโŸนโ€…โ€Š\implies ((3 : Nat) : Nat) โ€…โ€ŠโŸนโ€…โ€Š\implies 3 1.6.1. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Linked Lists) Lean์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” List๋ผ๋Š” ํ‘œ์ค€์ ์ธ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ ํƒ€์ž…๊ณผ ์ด๋ฅผ ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํŠน๋ณ„ํ•œ ๋ฌธ๋ฒ•์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ๋Š” ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 10 ๋ฏธ๋งŒ์˜ ์†Œ์ˆ˜๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def primesUnder10 : List Nat := [2, 3, 5, 7] ๋‚ด๋ถ€์ ์œผ๋กœ List๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋œ ๊ท€๋‚ฉ์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. inductive List (ฮฑ : Type) where | nil : List ฮฑ | cons : ฮฑ โ†’ List ฮฑ โ†’ List ฮฑ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‹ค์ œ ์ •์˜๋Š” ์•„์ง ์†Œ๊ฐœ๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„ ๋‹ค๋ฅด์ง€๋งŒ, ๋ณธ์งˆ์ ์œผ๋กœ๋Š” ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์ •์˜๋Š” List๊ฐ€ PPoint์ฒ˜๋Ÿผ ๋‹จ์ผ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›๋Š”๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ํƒ€์ž…์€ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ๋œ ํ•ญ๋ชฉ์˜ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž์— ๋”ฐ๋ฅด๋ฉด, List ฮฑ๋Š” nil ๋˜๋Š” cons๋กœ ๋งŒ๋“ค์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. nil ์ƒ์„ฑ์ž๋Š” ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , cons ์ƒ์„ฑ์ž๋Š” ๋น„์–ด์žˆ์ง€ ์•Š์€ ๋ฆฌ์ŠคํŠธ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. cons์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ๋ฆฌ์ŠคํŠธ์˜ head์ด๊ณ , ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š” tail์ž…๋‹ˆ๋‹ค. nn๊ฐœ์˜ ํ•ญ๋ชฉ์„ ํฌํ•จํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๋Š” nn๊ฐœ์˜ cons ์ƒ์„ฑ์ž๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ๋งˆ์ง€๋ง‰ cons๋Š” nil์„ ๊ผฌ๋ฆฌ๋กœ ๊ฐ€์ง‘๋‹ˆ๋‹ค. primesUnder10 ์˜ˆ์ œ๋Š” List์˜ ์ƒ์„ฑ์ž๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜์—ฌ ๋” ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def explicitPrimesUnder10 : List Nat := List.cons 2 (List.cons 3 (List.cons 5 (List.cons 7 List.nil))) ์ด ๋‘ ์ •์˜๋Š” ์™„์ „ํžˆ ๋™์ผํ•˜์ง€๋งŒ, primesUnder10์ด explicitPrimesUnder10๋ณด๋‹ค ํ›จ์”ฌ ์ฝ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. List๋ฅผ ์†Œ๋น„ํ•˜๋Š” ํ•จ์ˆ˜๋Š” Nat์„ ์†Œ๋น„ํ•˜๋Š” ํ•จ์ˆ˜์™€ ๊ฑฐ์˜ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ •์˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ, ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ succ ์ƒ์„ฑ์ž์—์„œ ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ ํ•„๋“œ๊ฐ€ ๋งค๋‹ฌ๋ ค ์žˆ๋Š” Nat์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ด€์ ์—์„œ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ณผ์ •์€ ๊ฐ cons๋ฅผ succ๋กœ, ๋งˆ์ง€๋ง‰ nil์„ 0์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. replaceX๊ฐ€ ์  ํ•„๋“œ์˜ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›์•˜๋˜ ๊ฒƒ์ฒ˜๋Ÿผ, length๋Š” ๋ฆฌ์ŠคํŠธ ํ•ญ๋ชฉ์˜ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ฌธ์ž์—ด์„ ํฌํ•จํ•œ๋‹ค๋ฉด ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” String์ž…๋‹ˆ๋‹ค: length String ["Sourdough", "bread"]. ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ„์‚ฐ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. length String ["Sourdough", "bread"] โ€…โ€ŠโŸนโ€…โ€Š\implies length String (List.cons "Sourdough" (List.cons "bread" List.nil)) โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (length String (List.cons "bread" List.nil)) โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (Nat.succ (length String List.nil)) โ€…โ€ŠโŸนโ€…โ€Š\implies Nat.succ (Nat.succ Nat.zero) โ€…โ€ŠโŸนโ€…โ€Š\implies 2 length์˜ ์ •์˜๋Š” ๋ฆฌ์ŠคํŠธ ํ•ญ๋ชฉ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋‹คํ˜•์ ์ด๋ฉด์„œ ์ž์‹ ์„ ์ฐธ์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์žฌ๊ท€์ ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ์˜ ํ˜•ํƒœ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์žฌ๊ท€์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์žฌ๊ท€ ํ•จ์ˆ˜๋กœ ์ด์–ด์ง€๊ณ , ๋‹คํ˜•์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ๋‹คํ˜•์  ํ•จ์ˆ˜๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. def length (ฮฑ : Type) (xs : List ฮฑ) : Nat := match xs with | List.nil => Nat.zero | List.cons y ys => Nat.succ (length ฮฑ ys) xs์™€ ys์™€ ๊ฐ™์€ ์ด๋ฆ„์€ ๊ด€๋ก€์ ์œผ๋กœ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฐ’๋“ค์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฆ„์˜ s๋Š” ๋ณต์ˆ˜ํ˜•์ž„์„ ๋‚˜ํƒ€๋‚ด๋ฏ€๋กœ, "x s"์™€ "y s"๊ฐ€ ์•„๋‹Œ "์—‘์‹œ์ฆˆ(exes)"์™€ "์™€์ด์ฆˆ(whys)"๋กœ ๋ฐœ์Œ๋ฉ๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•œ ํ•จ์ˆ˜๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก, ๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ• []์„ ์‚ฌ์šฉํ•˜์—ฌ nil์— ๋Œ€ํ•ด ํŒจํ„ด ๋งค์นญํ•  ์ˆ˜ ์žˆ๊ณ , cons ๋Œ€์‹  ์ค‘์œ„(infix) ์—ฐ์‚ฐ์ž ::๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def length (ฮฑ : Type) (xs : List ฮฑ) : Nat := match xs with | [] => 0 | y :: ys => Nat.succ (length ฮฑ ys) 1.6.2. ์•”์‹œ์  ์ธ์ž(Implicit Arguments) replaceX์™€ length๋Š” ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ธฐ์— ๋‹ค์†Œ ๋ฒˆ๊ฑฐ๋กœ์šด๋ฐ, ์™œ๋ƒํ•˜๋ฉด ํƒ€์ž… ์ธ์ž๋Š” ๋ณดํ†ต ์ดํ›„์˜ ๊ฐ’๋“ค์— ์˜ํ•ด ์œ ์ผํ•˜๊ฒŒ ๊ฒฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํƒ€์ž… ์ธ์ž๋ฅผ ์Šค์Šค๋กœ ์™„๋ฒฝํ•˜๊ฒŒ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๊ฐ€๋”์”ฉ๋งŒ ๋„์›€์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Lean์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ์ธ์ž๋ฅผ ๊ด„ํ˜ธ ๋Œ€์‹  ์ค‘๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ์„œ ์•”์‹œ์ ์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•”์‹œ์  ํƒ€์ž… ์ธ์ž๋ฅผ ๊ฐ€์ง„ replaceX ๋ฒ„์ „์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. def replaceX {ฮฑ : Type} (point : PPoint ฮฑ) (newX : ฮฑ) : PPoint ฮฑ := { point with x := newX } Lean์ด ์ดํ›„์˜ ์ธ์ž๋“ค๋กœ๋ถ€ํ„ฐ ฮฑ์˜ ๊ฐ’์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, Nat์„ ๋ช…์‹œ์ ์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ ๋„ natOrigin๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #eval replaceX natOrigin 5{ x := 5, y := 0 } ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, length๋„ ํ•ญ๋ชฉ ํƒ€์ž…์„ ์•”์‹œ์ ์œผ๋กœ ๋ฐ›๋„๋ก ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def length {ฮฑ : Type} (xs : List ฮฑ) : Nat := match xs with | [] => 0 | y :: ys => Nat.succ (length ys) ์ด length ํ•จ์ˆ˜๋Š” primesUnder10์— ์ง์ ‘ ์ ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #eval length primesUnder104 ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ Lean์€ ์ด ํ•จ์ˆ˜๋ฅผ List.length๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์ด๋Š” ๊ตฌ์กฐ์ฒด ํ•„๋“œ ์ ‘๊ทผ์— ์‚ฌ์šฉ๋˜๋Š” ์ (dot) ๋ฌธ๋ฒ•์ด ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด๋ฅผ ์ฐพ๋Š” ๋ฐ์—๋„ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. #eval primesUnder10.length4 C# ๊ณผ Java๊ฐ€ ๋•Œ๋•Œ๋กœ ํƒ€์ž… ์ธ์ž๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ œ๊ณตํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, Lean๋„ ํ•ญ์ƒ ์•”์‹œ์  ์ธ์ž๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ, ์ธ์ž ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ •์ˆ˜ ๋ฆฌ์ŠคํŠธ์—๋งŒ ์ž‘๋™ํ•˜๋Š” List.length ๋ฒ„์ „์€ ฮฑ๋ฅผ Int๋กœ ์„ค์ •ํ•˜์—ฌ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #check List.length (ฮฑ := Int)List.length : List Int โ†’ Nat 1.6.3. ๋” ๋งŽ์€ ๋‚ด์žฅ ๋ฐ์ดํ„ฐ ํƒ€์ž… Lean์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ๋ฆฌ์ŠคํŠธ ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ๋งฅ๋ฝ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ๊ตฌ์กฐ์ฒด์™€ ๊ท€๋‚ฉ์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. 1.6.3.1. Option ๋ชจ๋“  ๋ฆฌ์ŠคํŠธ์— ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์ด ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฆฌ์ŠคํŠธ๋Š” ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ๋งŽ์€ ์—ฐ์‚ฐ์€ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ์ฐพ์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฆฌ์ŠคํŠธ์—์„œ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์„ ์ฐพ๋Š” ํ•จ์ˆ˜๋Š” ๊ทธ๋Ÿฌํ•œ ํ•ญ๋ชฉ์„ ์ฐพ์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์ด ์—†์—ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ์–ธ์–ด์—๋Š” ๊ฐ’์˜ ๋ถ€์žฌ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” null ๊ฐ’์ด ์žˆ์Šต๋‹ˆ๋‹ค. Lean์€ ๊ธฐ์กด ํƒ€์ž…์— ํŠน๋ณ„ํ•œ null ๊ฐ’์„ ๋ถ€์—ฌํ•˜๋Š” ๋Œ€์‹ , Option์ด๋ผ๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ œ๊ณตํ•˜์—ฌ ๋‹ค๋ฅธ ํƒ€์ž…์— ๋ˆ„๋ฝ๋œ ๊ฐ’์„ ๋‚˜ํƒ€๋‚ด๋Š” ํ‘œ์‹œ์ž๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋„ ํ—ˆ์šฉ Int๋Š” Option Int๋กœ ํ‘œํ˜„๋˜๊ณ , ๋„ ํ—ˆ์šฉ ๋ฌธ์ž์—ด ๋ฆฌ์ŠคํŠธ๋Š” Option (List String) ํƒ€์ž…์œผ๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. ๋„ ํ—ˆ์šฉ์„ฑ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ๋„์ž…ํ•œ๋‹ค๋Š” ๊ฒƒ์€, Option Int๊ฐ€ Int๊ฐ€ ์˜ˆ์ƒ๋˜๋Š” ๋งฅ๋ฝ์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž… ์‹œ์Šคํ…œ์ด null ๊ฒ€์‚ฌ๋ฅผ ์žŠ์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. Option์—๋Š” some๊ณผ none์ด๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ƒ์„ฑ์ž๊ฐ€ ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ ๊ธฐ๋ณธ ํƒ€์ž…์˜ ๋„์ด ์•„๋‹Œ ๋ฒ„์ „๊ณผ ๋„ ๋ฒ„์ „์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๋„์ด ์•„๋‹Œ ์ƒ์„ฑ์ž์ธ some์€ ๊ธฐ๋ณธ ๊ฐ’์„ ํฌํ•จํ•˜๊ณ , none์€ ์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค: inductive Option (ฮฑ : Type) : Type where | none : Option ฮฑ | some (val : ฮฑ) : Option ฮฑ Option ํƒ€์ž…์€ C#์ด๋‚˜ Kotlin๊ณผ ๊ฐ™์€ ์–ธ์–ด์˜ ๋„ ํ—ˆ์šฉ ํƒ€์ž…๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•˜์ง€๋งŒ, ๋™์ผํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋“ค ์–ธ์–ด์—์„œ๋Š” ๋งŒ์•ฝ ์–ด๋–ค ํƒ€์ž…(์˜ˆ: Boolean)์ด ํ•ญ์ƒ ํ•ด๋‹น ํƒ€์ž…์˜ ์‹ค์ œ ๊ฐ’(true์™€ false)์„ ์ฐธ์กฐํ•œ๋‹ค๋ฉด, Boolean? ๋˜๋Š” Nullable<Boolean> ํƒ€์ž…์€ ์ถ”๊ฐ€์ ์œผ๋กœ null ๊ฐ’์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํƒ€์ž… ์‹œ์Šคํ…œ์—์„œ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž… ๊ฒ€์‚ฌ๊ธฐ์™€ ๋‹ค๋ฅธ ๋„๊ตฌ๋“ค์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ null ๊ฒ€์‚ฌ๋ฅผ ๊ธฐ์–ตํ•˜๋„๋ก ๋„์šธ ์ˆ˜ ์žˆ๊ณ , ํƒ€์ž… ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ํ†ตํ•ด ๋„ ํ—ˆ์šฉ์„ฑ์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ค๋ช…ํ•˜๋Š” API๋Š” ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ๋„ ํ—ˆ์šฉ ํƒ€์ž…์€ Lean์˜ Option๊ณผ ํ•œ ๊ฐ€์ง€ ๋งค์šฐ ์ค‘์š”ํ•œ ์ ์—์„œ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์—ฌ๋Ÿฌ ๊ณ„์ธต์˜ ์„ ํƒ์„ฑ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. Option (Option Int)๋Š” none, some none, ๋˜๋Š” some (some 360)์œผ๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— Kotlin์€ T??๋ฅผ T?์™€ ๋™์ผํ•˜๊ฒŒ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฏธ๋ฌ˜ํ•œ ์ฐจ์ด๋Š” ์‹ค์ œ๋กœ๋Š” ๊ฑฐ์˜ ๊ด€๋ จ์ด ์—†์ง€๋งŒ, ๋•Œ๋•Œ๋กœ ์ค‘์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์„ (์กด์žฌํ•œ๋‹ค๋ฉด) ์ฐพ์œผ๋ ค๋ฉด List.head?๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ์Œํ‘œ๋Š” ์ด๋ฆ„์˜ ์ผ๋ถ€์ด๋ฉฐ, C#์ด๋‚˜ Kotlin์—์„œ ๋„ ํ—ˆ์šฉ ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ฌผ์Œํ‘œ์™€๋Š” ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. List.head?์˜ ์ •์˜์—์„œ ๋ฐ‘์ค„์€ ๋ฆฌ์ŠคํŠธ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํŒจํ„ด์—์„œ ๋ฐ‘์ค„์€ ๋ฌด์—‡์ด๋“  ์ผ์น˜์‹œํ‚ค์ง€๋งŒ, ์ผ์น˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜๋ฅผ ๋„์ž…ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„ ๋Œ€์‹  ๋ฐ‘์ค„์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ž…๋ ฅ์˜ ์ผ๋ถ€๊ฐ€ ๋ฌด์‹œ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋…์ž์—๊ฒŒ ๋ช…ํ™•ํ•˜๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. def List.head? {ฮฑ : Type} (xs : List ฮฑ) : Option ฮฑ := match xs with | [] => none | y :: _ => some y Lean์˜ ๋ช…๋ช… ๊ทœ์น™์€ ์‹คํŒจํ•  ์ˆ˜ ์žˆ๋Š” ์—ฐ์‚ฐ์„ ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฃน์œผ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ?๋Š” Option์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฒ„์ „์—, !๋Š” ์œ ํšจํ•˜์ง€ ์•Š์€ ์ž…๋ ฅ์„ ์ œ๊ณตํ–ˆ์„ ๋•Œ ์ถฉ๋Œํ•˜๋Š” ๋ฒ„์ „์—, D๋Š” ์—ฐ์‚ฐ์ด ์‹คํŒจํ•  ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฒ„์ „์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์— ๋”ฐ๋ผ, List.head๋Š” ํ˜ธ์ถœ์ž๊ฐ€ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ์ง€ ์•Š๋‹ค๋Š” ์ˆ˜ํ•™์  ์ฆ๊ฑฐ๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์š”๊ตฌํ•˜๊ณ , List.head?๋Š” Option์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, List.head!๋Š” ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ „๋‹ฌ๋ฐ›์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์„ ์ถฉ๋Œ์‹œํ‚ค๊ณ , List.headD๋Š” ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ์„ ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๋ฌผ์Œํ‘œ์™€ ๋А๋‚Œํ‘œ๋Š” ํŠน๋ณ„ํ•œ ๊ตฌ๋ฌธ์ด ์•„๋‹ˆ๋ผ ์ด๋ฆ„์˜ ์ผ๋ถ€์ธ๋ฐ, ์ด๋Š” Lean์˜ ๋ช…๋ช… ๊ทœ์น™์ด ๋งŽ์€ ์–ธ์–ด๋ณด๋‹ค ๋” ์ž์œ ๋กญ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. head?๋Š” List ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, ์ ‘๊ทผ์ž ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: #eval primesUnder10.head?some 2 ๊ทธ๋Ÿฌ๋‚˜ ๋นˆ ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋‘ ๊ฐœ์˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค: #eval [].head?don't know how to synthesize implicit argument `ฮฑ` @List.nil ?m.3context:โŠข Type ?u.71735don't know how to synthesize implicit argument `ฮฑ` @_root_.List.head? ?m.3 []context:โŠข Type ?u.71735 ์ด๋Š” Lean์ด ํ‘œํ˜„์‹์˜ ํƒ€์ž…์„ ์™„์ „ํžˆ ๊ฒฐ์ •ํ•  ์ˆ˜ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ, List.head?์— ๋Œ€ํ•œ ์•”์‹œ์  ํƒ€์ž… ์ธ์ž์™€ List.nil์— ๋Œ€ํ•œ ์•”์‹œ์  ํƒ€์ž… ์ธ์ž๋ฅผ ๋ชจ๋‘ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. Lean์˜ ์ถœ๋ ฅ์—์„œ ?m.XYZ๋Š” ์ถ”๋ก ํ•  ์ˆ˜ ์—†์—ˆ๋˜ ํ”„๋กœ๊ทธ๋žจ์˜ ์ผ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์•Œ ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„์„ ๋ฉ”ํƒ€๋ณ€์ˆ˜๋ผ๊ณ  ํ•˜๋ฉฐ, ์ผ๋ถ€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์— ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด Lean์€ ๊ทธ ํƒ€์ž…์„ ์ฐพ์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋Š”๋ฐ, ๋นˆ ๋ฆฌ์ŠคํŠธ์—๋Š” ํƒ€์ž…์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ํ•ญ๋ชฉ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ž…์„ ์ œ๊ณตํ•˜๋ฉด Lean์ด ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: #eval [].head? (ฮฑ := Int)none ํƒ€์ž…์€ ํƒ€์ž… ์ฃผ์„์œผ๋กœ๋„ ์ œ๊ณต๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: #eval ([] : List Int).head?none ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ์œ ์šฉํ•œ ๋‹จ์„œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฉ”์‹œ์ง€ ๋ชจ๋‘ ๋ˆ„๋ฝ๋œ ์•”์‹œ์  ์ธ์ž๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๋™์ผํ•œ ๋ฉ”ํƒ€๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด๋Š” Lean์ด ํ•ด๊ฒฐ์ฑ…์˜ ์‹ค์ œ ๊ฐ’์„ ๊ฒฐ์ •ํ•  ์ˆ˜๋Š” ์—†์—ˆ์ง€๋งŒ ๋‘ ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์ด ๋™์ผํ•œ ํ•ด๊ฒฐ์ฑ…์„ ๊ณต์œ ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฒฐ์ •ํ–ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. 1.6.3.2. Prod "Product"์˜ ์•ฝ์ž์ธ Prod ๊ตฌ์กฐ์ฒด๋Š” ๋‘ ๊ฐ’์„ ํ•จ๊ป˜ ๋ฌถ๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Prod Nat String์€ Nat๊ณผ String์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, PPoint Nat์€ Prod Nat Nat์œผ๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Prod๋Š” C#์˜ ํŠœํ”Œ, Kotlin์˜ Pair ๋ฐ Triple ํƒ€์ž…, C++์˜ tuple๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” Point์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์—๋„ ์ž์ฒด ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋„๋ฉ”์ธ ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ, ๊ตฌ์กฐ์ฒด ํƒ€์ž…์„ ์ •์˜ํ•˜๋ฉด ๋‹ค๋ฅธ ๋„๋ฉ”์ธ ๊ฐœ๋…์— ๋‹ค๋ฅธ ํƒ€์ž…์„ ํ• ๋‹นํ•˜์—ฌ ์„œ๋กœ ์„ž์ด๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•จ์œผ๋กœ์จ ๋” ๋งŽ์€ ์˜ค๋ฅ˜๋ฅผ ์žก๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์—, ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์ •์˜ํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๊ฐ€์น˜๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” "์Œ"๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ธ ๊ฐœ๋…์ด ์—†์„ ์ •๋„๋กœ ์ถฉ๋ถ„ํžˆ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ๋‚ด์žฅ๋œ ์Œ ํƒ€์ž…์„ ๋” ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋‹ค์–‘ํ•œ ํŽธ์˜ ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Prod ๊ตฌ์กฐ์ฒด๋Š” ๋‘ ๊ฐœ์˜ ํƒ€์ž… ์ธ์ž๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค: structure Prod (ฮฑ : Type) (ฮฒ : Type) : Type where fst : ฮฑ snd : ฮฒ ๋ฆฌ์ŠคํŠธ๋Š” ๋งค์šฐ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ํŠน๋ณ„ํ•œ ๊ตฌ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ™์€ ์ด์œ ๋กœ, ํ”„๋กœ๋•ํŠธ ํƒ€์ž…๊ณผ ๊ทธ ์ƒ์„ฑ์ž ๋ชจ๋‘ ํŠน๋ณ„ํ•œ ๊ตฌ๋ฌธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Prod ฮฑ ฮฒ ํƒ€์ž…์€ ์ผ๋ฐ˜์ ์œผ๋กœ ฮฑ ร— ฮฒ๋กœ ์“ฐ์ด๋ฉฐ, ์ด๋Š” ์ง‘ํ•ฉ์˜ ๋ฐ์นด๋ฅดํŠธ ๊ณฑ์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ ํ‘œ๊ธฐ๋ฒ•์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์Œ์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ ์ˆ˜ํ•™์  ํ‘œ๊ธฐ๋ฒ•์„ Prod์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ฐ๋Š” ๋Œ€์‹ ์—: def fives : String ร— Int := { fst := "five", snd := 5 } ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์“ฐ๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค: def fives : String ร— Int := ("five", 5) ๋‘ ํ‘œ๊ธฐ๋ฒ• ๋ชจ๋‘ ์˜ค๋ฅธ์ชฝ ๊ฒฐํ•ฉ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค์Œ ์ •์˜๋“ค์ด ๋™์ผํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค: def sevens : String ร— Int ร— Nat := ("VII", 7, 4 + 3)def sevens : String ร— (Int ร— Nat) := ("VII", (7, 4 + 3)) ์ฆ‰, ์„ธ ๊ฐœ ์ด์ƒ์˜ ํƒ€์ž…์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ๋ชจ๋“  ํ”„๋กœ๋•ํŠธ์™€ ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ์ƒ์„ฑ์ž๋“ค์€ ์‹ค์ œ๋กœ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ค‘์ฒฉ๋œ ํ”„๋กœ๋•ํŠธ์™€ ์ค‘์ฒฉ๋œ ์Œ์ž…๋‹ˆ๋‹ค. 1.6.3.3. Sum Sum ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ํƒ€์ž…์˜ ๊ฐ’ ์‚ฌ์ด์—์„œ ์„ ํƒ์„ ํ—ˆ์šฉํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Sum String Int๋Š” String์ด๊ฑฐ๋‚˜ Int์ž…๋‹ˆ๋‹ค. Prod์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, Sum์€ ๋งค์šฐ ์ผ๋ฐ˜์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ, ํ•ฉ๋ฆฌ์ ์ธ ๋„๋ฉ”์ธ ํŠน์ • ํƒ€์ž…์ด ์—†๋Š” ๋งค์šฐ ์ž‘์€ ์ฝ”๋“œ ์„น์…˜์— ๋Œ€ํ•ด, ๋˜๋Š” ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์œ ์šฉํ•œ ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์„ ๋•Œ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ™ฉ์—์„œ๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ๊ท€๋‚ฉ์  ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๊ฐ€๋…์„ฑ์ด ์ข‹๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. Sum ฮฑ ฮฒ ํƒ€์ž…์˜ ๊ฐ’์€ ฮฑ ํƒ€์ž…์˜ ๊ฐ’์— ์ ์šฉ๋œ ์ƒ์„ฑ์ž inl์ด๊ฑฐ๋‚˜ ฮฒ ํƒ€์ž…์˜ ๊ฐ’์— ์ ์šฉ๋œ ์ƒ์„ฑ์ž inr์ž…๋‹ˆ๋‹ค: inductive Sum (ฮฑ : Type) (ฮฒ : Type) : Type where | inl : ฮฑ โ†’ Sum ฮฑ ฮฒ | inr : ฮฒ โ†’ Sum ฮฑ ฮฒ ์ด ์ด๋ฆ„๋“ค์€ ๊ฐ๊ฐ "์™ผ์ชฝ ์‚ฌ์ƒ(left injection)"๊ณผ "์˜ค๋ฅธ์ชฝ ์‚ฌ์ƒ(right injection)"์˜ ์•ฝ์–ด์ž…๋‹ˆ๋‹ค. Prod์— ๋ฐ์นด๋ฅดํŠธ ๊ณฑ ํ‘œ๊ธฐ๋ฒ•์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, Sum์—๋Š” "๋™๊ทธ๋ผ๋ฏธ ์•ˆ์˜ ๋”ํ•˜๊ธฐ" ํ‘œ๊ธฐ๋ฒ•์ด ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ฮฑ โŠ• ฮฒ๋Š” Sum ฮฑ ฮฒ๋ฅผ ์“ฐ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. Sum.inl๊ณผ Sum.inr์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ๊ตฌ๋ฌธ์€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์• ์™„๋™๋ฌผ ์ด๋ฆ„์ด ๊ฐœ ์ด๋ฆ„์ด๊ฑฐ๋‚˜ ๊ณ ์–‘์ด ์ด๋ฆ„์ผ ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๊ทธ๋“ค์„ ์œ„ํ•œ ํƒ€์ž…์€ ๋ฌธ์ž์—ด์˜ ํ•ฉ์œผ๋กœ ๋„์ž…๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def PetName : Type := String โŠ• String ์‹ค์ œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š”, ์œ ์ตํ•œ ์ƒ์„ฑ์ž ์ด๋ฆ„์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž ์ •์˜ ๊ท€๋‚ฉ์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ด ๋ชฉ์ ์œผ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ๋ณดํ†ต ๋” ์ข‹์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š”, Sum.inl์€ ๊ฐœ ์ด๋ฆ„์—, Sum.inr์€ ๊ณ ์–‘์ด ์ด๋ฆ„์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ์ƒ์„ฑ์ž๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™๋ฌผ ์ด๋ฆ„ ๋ชฉ๋ก์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def animals : List PetName := [Sum.inl "Spot", Sum.inr "Tiger", Sum.inl "Fifi", Sum.inl "Rex", Sum.inr "Floof"] ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์ƒ์„ฑ์ž๋ฅผ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋™๋ฌผ ์ด๋ฆ„ ๋ชฉ๋ก์—์„œ ๊ฐœ์˜ ์ˆ˜(์ฆ‰, Sum.inl ์ƒ์„ฑ์ž์˜ ์ˆ˜)๋ฅผ ์„ธ๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: def howManyDogs (pets : List PetName) : Nat := match pets with | [] => 0 | Sum.inl _ :: morePets => howManyDogs morePets + 1 | Sum.inr _ :: morePets => howManyDogs morePets ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ์ค‘์œ„ ์—ฐ์‚ฐ์ž๋ณด๋‹ค ๋จผ์ € ํ‰๊ฐ€๋˜๋ฏ€๋กœ, howManyDogs morePets + 1์€ (howManyDogs morePets) + 1๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์˜ˆ์ƒ๋Œ€๋กœ, #eval howManyDogs animals๋Š” 3์„ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค. 1.6.3.4. Unit Unit์€ unit์ด๋ผ๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์ธ์ž ์—†๋Š” ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง„ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๊ทธ๊ฒƒ์€ ๋‹จ ํ•˜๋‚˜์˜ ๊ฐ’๋งŒ์„ ์„ค๋ช…ํ•˜๋ฉฐ, ์ด ๊ฐ’์€ ์•„๋ฌด ์ธ์ž์—๋„ ์ ์šฉ๋˜์ง€ ์•Š์€ ํ•ด๋‹น ์ƒ์„ฑ์ž๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. Unit์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋ฉ๋‹ˆ๋‹ค: inductive Unit : Type where | unit : Unit ๊ทธ ์ž์ฒด๋กœ Unit์€ ํŠน๋ณ„ํžˆ ์œ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹คํ˜•์„ฑ ์ฝ”๋“œ์—์„œ๋Š” ๋ˆ„๋ฝ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ์ž๋ฆฌ ํ‘œ์‹œ์ž๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ๊ท€๋‚ฉ์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์‚ฐ์ˆ  ํ‘œํ˜„์‹์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค: inductive ArithExpr (ann : Type) : Type where | int : ann โ†’ Int โ†’ ArithExpr ann | plus : ann โ†’ ArithExpr ann โ†’ ArithExpr ann โ†’ ArithExpr ann | minus : ann โ†’ ArithExpr ann โ†’ ArithExpr ann โ†’ ArithExpr ann | times : ann โ†’ ArithExpr ann โ†’ ArithExpr ann โ†’ ArithExpr ann ํƒ€์ž… ์ธ์ž ann์€ ์ฃผ์„์„ ์˜๋ฏธํ•˜๋ฉฐ, ๊ฐ ์ƒ์„ฑ์ž๋Š” ์ฃผ์„์ด ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์„œ์—์„œ ์˜ค๋Š” ํ‘œํ˜„์‹์€ ์†Œ์Šค ์œ„์น˜๋กœ ์ฃผ์„์ด ๋‹ฌ๋ฆด ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ArithExpr SourcePos์ด๋ฉด ํŒŒ์„œ๊ฐ€ ๊ฐ ํ•˜์œ„ ํ‘œํ˜„์‹์— SourcePos๋ฅผ ๋„ฃ์—ˆ์Œ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŒŒ์„œ์—์„œ ์˜ค์ง€ ์•Š์€ ํ‘œํ˜„์‹์€ ์†Œ์Šค ์œ„์น˜๊ฐ€ ์—†์œผ๋ฏ€๋กœ, ๊ทธ ํƒ€์ž…์€ ArithExpr Unit์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋ชจ๋“  Lean ํ•จ์ˆ˜๋Š” ์ธ์ž๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ, ๋‹ค๋ฅธ ์–ธ์–ด์˜ ์ธ์ž ์—†๋Š” ํ•จ์ˆ˜๋Š” Unit ์ธ์ž๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜๋กœ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ ์œ„์น˜์—์„œ Unit ํƒ€์ž…์€ C์—์„œ ํŒŒ์ƒ๋œ ์–ธ์–ด์˜ void์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. C ๊ณ„์—ด์—์„œ void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ์ž์—๊ฒŒ ์ œ์–ด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, ํฅ๋ฏธ๋กœ์šด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์˜๋„์ ์œผ๋กœ ํฅ๋ฏธ๋กญ์ง€ ์•Š์€ ๊ฐ’์ด ๋จ์œผ๋กœ์จ, Unit์€ ํƒ€์ž… ์‹œ์Šคํ…œ์— ํŠน์ˆ˜ ๋ชฉ์ ์˜ void ๊ธฐ๋Šฅ์ด ํ•„์š” ์—†์ด ์ด๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. Unit์˜ ์ƒ์„ฑ์ž๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋นˆ ๊ด„ํ˜ธ๋กœ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: () : Unit. 1.6.3.5. Empty Empty ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์ƒ์„ฑ์ž๊ฐ€ ์ „ํ˜€ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์–ด๋–ค ์ผ๋ จ์˜ ํ˜ธ์ถœ๋„ Empty ํƒ€์ž…์˜ ๊ฐ’์œผ๋กœ ๋๋‚  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. Empty๋Š” Unit๋งŒํผ ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ถ€ ํŠน์ˆ˜ํ•œ ๋งฅ๋ฝ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ๋‹คํ˜•์„ฑ ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ๋ชจ๋“  ์ƒ์„ฑ์ž์—์„œ ๋ชจ๋“  ํƒ€์ž… ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Sum.inl๊ณผ Sum.inr๋Š” ๊ฐ๊ฐ Sum์˜ ํƒ€์ž… ์ธ์ž ์ค‘ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Sum์˜ ํƒ€์ž… ์ธ์ž ์ค‘ ํ•˜๋‚˜๋กœ Empty๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์˜ ํŠน์ • ์ง€์ ์—์„œ ์ƒ์„ฑ์ž ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฐฐ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€์ ์ธ ์ œ์•ฝ์ด ์žˆ๋Š” ๋งฅ๋ฝ์—์„œ ์ผ๋ฐ˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.1.6.3.6. ์ด๋ฆ„ ์ง“๊ธฐ: ํ•ฉ, ๊ณฑ, ๊ทธ๋ฆฌ๊ณ  ์œ ๋‹›๐Ÿ”— ์ผ๋ฐ˜์ ์œผ๋กœ, ์—ฌ๋Ÿฌ ์ƒ์„ฑ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š” ํƒ€์ž…์„ ํ•ฉ ํƒ€์ž…(sum type)์ด๋ผ๊ณ  ํ•˜๊ณ , ๋‹จ์ผ ์ƒ์„ฑ์ž๊ฐ€ ์—ฌ๋Ÿฌ ์ธ์ž๋ฅผ ๋ฐ›๋Š” ํƒ€์ž…์„ ๊ณฑ ํƒ€์ž…(product type)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด ์šฉ์–ด๋“ค์€ ์ผ๋ฐ˜ ์‚ฐ์ˆ ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•ฉ๊ณผ ๊ณฑ๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ด€๊ณ„๋Š” ๊ด€๋ จ๋œ ํƒ€์ž…๋“ค์ด ์œ ํ•œํ•œ ์ˆ˜์˜ ๊ฐ’์„ ํฌํ•จํ•  ๋•Œ ๊ฐ€์žฅ ์‰ฝ๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ฮฑ์™€ ฮฒ๊ฐ€ ๊ฐ๊ฐ n๊ฐœ์™€ k๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ํƒ€์ž…์ด๋ผ๋ฉด, ฮฑ โŠ• ฮฒ๋Š” n+k๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ’์„ ํฌํ•จํ•˜๊ณ  ฮฑ ร— ฮฒ๋Š” nร—k๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ’์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Bool์€ true์™€ false ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ๊ฐ€์ง€๊ณ , Unit์€ Unit.unit์ด๋ผ๋Š” ํ•˜๋‚˜์˜ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๊ณฑ Bool ร— Unit์€ (true, Unit.unit)๊ณผ (false, Unit.unit) ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ๊ฐ€์ง€๊ณ , ํ•ฉ Bool โŠ• Unit์€ Sum.inl true, Sum.inl false, Sum.inr Unit.unit ์„ธ ๊ฐœ์˜ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, 2ร—1=2์ด๊ณ , 2+1=3์ž…๋‹ˆ๋‹ค. 1.6.4. ๋งˆ์ฃผ์น  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์‹œ์ง€๋“ค ์ •์˜ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ตฌ์กฐ์ฒด๋‚˜ ๊ท€๋‚ฉ์  ํƒ€์ž…์ด Type ํƒ€์ž…์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ํŠนํžˆ, ์ƒ์„ฑ์ž๊ฐ€ ์ž„์˜์˜ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ๊ฒฝ์šฐ, ๊ท€๋‚ฉ์  ํƒ€์ž…์€ ๋‹ค๋ฅธ ํƒ€์ž…์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋Š” ๋ณดํ†ต "์œ ๋‹ˆ๋ฒ„์Šค ๋ ˆ๋ฒจ"์— ๋Œ€ํ•œ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ๊ท€๋‚ฉ์  ํƒ€์ž…์— ๋Œ€ํ•ด: inductive MyType : Type where | ctor : (ฮฑ : Type) โ†’ ฮฑ โ†’ MyType Lean์€ ๋‹ค์Œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค: Invalid universe level in constructor `MyType.ctor`: Parameter `ฮฑ` has type Typeat universe level 2which is not less than or equal to the inductive type's resulting universe level 1 ์ด๊ฒƒ์ด ์™œ ๊ทธ๋Ÿฐ์ง€, ๊ทธ๋ฆฌ๊ณ  ์ •์˜๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์ž‘๋™ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ๋‚˜์ค‘ ์žฅ์—์„œ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ํƒ€์ž…์„ ์ƒ์„ฑ์ž์— ๋Œ€ํ•œ ์ธ์ž๊ฐ€ ์•„๋‹Œ ๊ท€๋‚ฉ์  ํƒ€์ž… ์ „์ฒด์— ๋Œ€ํ•œ ์ธ์ž๋กœ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ƒ์„ฑ์ž์˜ ์ธ์ž๊ฐ€ ์ •์˜๋˜๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜์ธ ๊ฒฝ์šฐ, ์ •์˜๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด: inductive MyType : Type where | ctor : (MyType โ†’ Int) โ†’ MyType ๋‹ค์Œ ๋ฉ”์‹œ์ง€๋ฅผ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค: (kernel) arg #1 of 'MyType.ctor' has a non positive occurrence of the datatypes being declared ๊ธฐ์ˆ ์ ์ธ ์ด์œ ๋กœ, ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ํ—ˆ์šฉํ•˜๋ฉด Lean์˜ ๋‚ด๋ถ€ ๋…ผ๋ฆฌ๋ฅผ ์•ฝํ™”์‹œ์ผœ ์ •๋ฆฌ ์ฆ๋ช…๊ธฐ๋กœ์„œ ์‚ฌ์šฉํ•˜๊ธฐ์— ๋ถ€์ ํ•ฉํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ์žฌ๊ท€ ํ•จ์ˆ˜๋Š” ์Œ์— ๋Œ€ํ•ด ๋งค์น˜ํ•ด์„œ๋Š” ์•ˆ ๋˜๋ฉฐ, ๊ฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๋งค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, Lean์—์„œ ์žฌ๊ท€ ํ˜ธ์ถœ์ด ๋” ์ž‘์€ ๊ฐ’์— ๋Œ€ํ•ด ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์ž…๋ ฅ ๊ฐ’๊ณผ ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ์ธ์ž ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์„ ๋ณผ ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‘ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด๊ฐ€ ๊ฐ™์€์ง€ ํŒ๋ณ„ํ•˜๋Š” ์ด ํ•จ์ˆ˜๋Š” ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค: def sameLength (xs : List ฮฑ) (ys : List ฮฒ) : Bool := match (xs, ys) with | ([], []) => true | (x :: xs', y :: ys') => sameLength xs' ys' | _ => false ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: fail to show termination for sameLengthwith errorsfailed to infer structural recursion:Not considering parameter ฮฑ of sameLength: it is unchanged in the recursive callsNot considering parameter ฮฒ of sameLength: it is unchanged in the recursive callsCannot use parameter xs: failed to eliminate recursive application sameLength xs' ys'Cannot use parameter ys: failed to eliminate recursive application sameLength xs' ys'Could not find a decreasing measure.The basic measures relate at each recursive call as follows:(<, โ‰ค, =: relation proved, ? all proofs failed, _: no proof attempted) xs ys1) 1816:28-46 ? ?Please use `termination_by` to specify a decreasing measure. ์ด ๋ฌธ์ œ๋Š” ์ค‘์ฒฉ๋œ ํŒจํ„ด ๋งค์นญ์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def sameLength (xs : List ฮฑ) (ys : List ฮฒ) : Bool := match xs with | [] => match ys with | [] => true | _ => false | x :: xs' => match ys with | y :: ys' => sameLength xs' ys' | _ => false ๋‹ค์Œ ์„น์…˜์—์„œ ์„ค๋ช…ํ•˜๋Š” ๋™์‹œ ๋งค์นญ์€ ์ข…์ข… ๋” ์šฐ์•„ํ•˜๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๊ท€๋‚ฉ์  ํƒ€์ž…์— ๋Œ€ํ•œ ์ธ์ž๋ฅผ ์žŠ์–ด๋ฒ„๋ฆฌ๋Š” ๊ฒƒ๋„ ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ๋ฉ”์‹œ์ง€๋ฅผ ๋‚ณ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ctor์˜ ํƒ€์ž…์—์„œ MyType์— ์ธ์ž ฮฑ๊ฐ€ ์ „๋‹ฌ๋˜์ง€ ์•Š์•˜์„ ๋•Œ: inductive MyType (ฮฑ : Type) : Type where | ctor : ฮฑ โ†’ MyType Lean์€ ๋‹ค์Œ ์˜ค๋ฅ˜๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค: type expected, got (MyType : Type โ†’ Type) ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” MyType์˜ ํƒ€์ž…์ธ Type โ†’ Type์ด ๊ทธ ์ž์ฒด๋กœ๋Š” ํƒ€์ž…์„ ์„ค๋ช…ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. MyType์€ ์‹ค์ œ ์ •์งํ•œ ํƒ€์ž…์ด ๋˜๊ธฐ ์œ„ํ•ด ์ธ์ž๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ •์˜์˜ ํƒ€์ž… ์‹œ๊ทธ๋‹ˆ์ฒ˜์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋งฅ๋ฝ์—์„œ ํƒ€์ž… ์ธ์ž๊ฐ€ ์ƒ๋žต๋  ๋•Œ๋„ ๋™์ผํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: inductive MyType (ฮฑ : Type) : Type where | ctor : ฮฑ โ†’ MyType ฮฑdef ofFive : MyType := ctor 5type expected, got (MyType : Type โ†’ Type) ๋‹คํ˜•์„ฑ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜๋ฉด Lean์ด ๊ฐ’์„ ํ‘œ์‹œํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #eval ๋ช…๋ น์–ด๋Š” ์ œ๊ณต๋œ ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜๊ณ , ํ‘œํ˜„์‹์˜ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜์™€ ๊ฐ™์€ ์ผ๋ถ€ ํƒ€์ž…์˜ ๊ฒฝ์šฐ ์ด ๊ณผ์ •์ด ์‹คํŒจํ•˜์ง€๋งŒ, Lean์€ ๋Œ€๋ถ€๋ถ„์˜ ๋‹ค๋ฅธ ํƒ€์ž…์— ๋Œ€ํ•ด ํ‘œ์‹œ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, WoodSplittingTool์— ๋Œ€ํ•ด Lean์— ํŠน์ • ํ‘œ์‹œ ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค: inductive WoodSplittingTool where | axe | maul | froe#eval WoodSplittingTool.axeWoodSplittingTool.axe ๊ทธ๋Ÿฌ๋‚˜ Lean์ด ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•˜๋Š” ์ž๋™ํ™”์—๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. allTools๋Š” ์„ธ ๊ฐ€์ง€ ๋„๊ตฌ ๋ชจ๋‘๋ฅผ ๋‹ด์€ ๋ฆฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค: def allTools : List WoodSplittingTool := [ WoodSplittingTool.axe, WoodSplittingTool.maul, WoodSplittingTool.froe] ์ด๋ฅผ ํ‰๊ฐ€ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค: #eval allToolscould not synthesize a `ToExpr`, `Repr`, or `ToString` instance for type List WoodSplittingTool ์ด๋Š” Lean์ด ๋ฆฌ์ŠคํŠธ๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด์žฅ ํ…Œ์ด๋ธ”์˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€๋งŒ, ์ด ์ฝ”๋“œ๋Š” WoodSplittingTool์— ๋Œ€ํ•œ ํ‘œ์‹œ ์ฝ”๋“œ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์š”๊ตฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ์˜ค๋ฅ˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ •์˜ํ•  ๋•Œ #eval์˜ ์ผ๋ถ€๋กœ ๋งˆ์ง€๋ง‰ ์ˆœ๊ฐ„์— ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹ , Lean์—๊ฒŒ ์ด ํ‘œ์‹œ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•จ์œผ๋กœ์จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ •์˜์— deriving Repr์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค: inductive Firewood where | birch | pine | beechderiving Repr Firewood ๋ฆฌ์ŠคํŠธ๋ฅผ ํ‰๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์„ฑ๊ณตํ•ฉ๋‹ˆ๋‹ค: def allFirewood : List Firewood := [ Firewood.birch, Firewood.pine, Firewood.beech]#eval allFirewood[Firewood.birch, Firewood.pine, Firewood.beech] 1.6.5. ์—ฐ์Šต ๋ฌธ์ œ ๋ฆฌ์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์„ ์ฐพ๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ์ด ํ•จ์ˆ˜๋Š” Option์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ์ˆ ์–ด๋ฅผ ๋งŒ์กฑํ•˜๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์„ ์ฐพ๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ์ •์˜๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์‹œ์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค:def List.findFirst? {ฮฑ : Type} (xs : List ฮฑ) (predicate : ฮฑ โ†’ Bool) : Option ฮฑ := ์Œ์˜ ๋‘ ํ•„๋“œ๋ฅผ ์„œ๋กœ ๋ฐ”๊พธ๋Š” Prod.switch ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ์ •์˜๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์‹œ์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค:def Prod.switch {ฮฑ ฮฒ : Type} (pair : ฮฑ ร— ฮฒ) : ฮฒ ร— ฮฑ := PetName ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋‹ค์‹œ ์ž‘์„ฑํ•˜๊ณ  Sum์„ ์‚ฌ์šฉํ•œ ๋ฒ„์ „๊ณผ ๋น„๊ตํ•ด ๋ณด์„ธ์š”. ๋‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์Œ์˜ ๋ฆฌ์ŠคํŠธ๋กœ ๊ฒฐํ•ฉํ•˜๋Š” zip ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ๊ฒฐ๊ณผ ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ€์žฅ ์งง์€ ์ž…๋ ฅ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด์™€ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ •์˜๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์‹œ์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค:def zip {ฮฑ ฮฒ : Type} (xs : List ฮฑ) (ys : List ฮฒ) : List (ฮฑ ร— ฮฒ) := ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ n๊ฐœ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‹คํ˜•์„ฑ ํ•จ์ˆ˜ take๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ์—ฌ๊ธฐ์„œ n์€ Nat์ž…๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์— n๊ฐœ ๋ฏธ๋งŒ์˜ ํ•ญ๋ชฉ์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ, ๊ฒฐ๊ณผ ๋ฆฌ์ŠคํŠธ๋Š” ์ „์ฒด ์ž…๋ ฅ ๋ฆฌ์ŠคํŠธ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. #eval take 3 ["bolete", "oyster"]๋Š” ["bolete", "oyster"]๋ฅผ ์‚ฐ์ถœํ•ด์•ผ ํ•˜๊ณ , #eval take 1 ["bolete", "oyster"]๋Š” ["bolete"]๋ฅผ ์‚ฐ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž…๊ณผ ์‚ฐ์ˆ  ์‚ฌ์ด์˜ ์œ ์ถ”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ๊ณฑ์„ ํ•ฉ์— ๋Œ€ํ•ด ๋ถ„๋ฐฐํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ์ฆ‰, ์ด ํ•จ์ˆ˜๋Š” ฮฑ ร— (ฮฒ โŠ• ฮณ) โ†’ (ฮฑ ร— ฮฒ) โŠ• (ฮฑ ร— ฮณ) ํƒ€์ž…์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž…๊ณผ ์‚ฐ์ˆ  ์‚ฌ์ด์˜ ์œ ์ถ”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, 2๋ฅผ ๊ณฑํ•˜๋Š” ๊ฒƒ์„ ํ•ฉ์œผ๋กœ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. ์ฆ‰, ์ด ํ•จ์ˆ˜๋Š” Bool ร— ฮฑ โ†’ ฮฑ โŠ• ฮฑ ํƒ€์ž…์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. 1.7. ์ถ”๊ฐ€์ ์ธ ํŽธ์˜ ๊ธฐ๋Šฅ Lean์—๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ํ›จ์”ฌ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์—ฌ๋Ÿฌ ํŽธ์˜ ๊ธฐ๋Šฅ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. 1.7.1. ์ž๋™ ์•”์‹œ์  ๋งค๊ฐœ๋ณ€์ˆ˜ Lean์—์„œ ๋‹คํ˜•์„ฑ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ๋•Œ, ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ์•”์‹œ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋‚˜์—ดํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ๊ทธ๋ƒฅ ์–ธ๊ธ‰ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. Lean์ด ๊ทธ ํƒ€์ž…์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์€ ์ž๋™์œผ๋กœ ์•”์‹œ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด, ์ด์ „์— ์ •์˜ํ–ˆ๋˜ length๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. def length {ฮฑ : Type} (xs : List ฮฑ) : Nat := match xs with | [] => 0 | y :: ys => Nat.succ (length ys) ์ด ์ •์˜๋Š” {ฮฑ : Type} ์—†์ด๋„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def length (xs : List ฮฑ) : Nat := match xs with | [] => 0 | y :: ys => Nat.succ (length ys) ์ด ๊ธฐ๋Šฅ์€ ๋งŽ์€ ์•”์‹œ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ณ ๋„๋กœ ๋‹คํ˜•์ ์ธ ์ •์˜๋ฅผ ํฌ๊ฒŒ ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1.7.2. ํŒจํ„ด ๋งค์นญ ์ •์˜ def๋กœ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ, ์ธ์ž์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•œ ํ›„ ๋ฐ”๋กœ ํŒจํ„ด ๋งค์นญ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ํ”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, length์—์„œ ์ธ์ž xs๋Š” match์—์„œ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ๋Š” ์ธ์ž์˜ ์ด๋ฆ„์„ ์ „ํ˜€ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  match ํ‘œํ˜„์‹์˜ ์ผ€์ด์Šค๋“ค์„ ์ง์ ‘ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ์ธ์ž์˜ ํƒ€์ž…์„ ์ฝœ๋ก  ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์˜ฎ๊ฒจ์„œ ๋ฐ˜ํ™˜ ํƒ€์ž…์ด ํ•จ์ˆ˜ ํƒ€์ž…์ด ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, length์˜ ํƒ€์ž…์€ List ฮฑ โ†’ Nat์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, :=๋ฅผ ๊ฐ ํŒจํ„ด ๋งค์นญ ์ผ€์ด์Šค๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. def length : List ฮฑ โ†’ Nat | [] => 0 | y :: ys => Nat.succ (length ys) ์ด ๊ตฌ๋ฌธ์€ ํ•˜๋‚˜ ์ด์ƒ์˜ ์ธ์ž๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ํŒจํ„ด๋“ค์€ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, drop์€ ์ˆซ์ž nn๊ณผ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ›์•„ ์ฒ˜์Œ nn๊ฐœ์˜ ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•œ ํ›„์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. def drop : Nat โ†’ List ฮฑ โ†’ List ฮฑ | Nat.zero, xs => xs | _, [] => [] | Nat.succ n, x :: xs => drop n xs ์ด๋ฆ„์ด ์ง€์ •๋œ ์ธ์ž์™€ ํŒจํ„ด์„ ๊ฐ™์€ ์ •์˜ ์•ˆ์—์„œ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ธฐ๋ณธ๊ฐ’๊ณผ ์˜ต์…”๋„ ๊ฐ’์„ ๋ฐ›์•„ ์˜ต์…”๋„ ๊ฐ’์ด none์ผ ๋•Œ ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def fromOption (default : ฮฑ) : Option ฮฑ โ†’ ฮฑ | none => default | some x => x ์ด ํ•จ์ˆ˜๋Š” ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ Option.getD๋ผ๊ณ  ๋ถˆ๋ฆฌ๋ฉฐ, ์  ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #eval (some "salmonberry").getD """salmonberry"#eval none.getD """" 1.7.3. ์ง€์—ญ ์ •์˜ ๊ณ„์‚ฐ ๊ณผ์ •์—์„œ ์ค‘๊ฐ„ ๋‹จ๊ณ„๋ฅผ ๋ช…๋ช…ํ•˜๋Š” ๊ฒƒ์€ ์ข…์ข… ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ๊ฒฝ์šฐ, ์ค‘๊ฐ„๊ฐ’๋“ค์€ ๊ทธ ์ž์ฒด๋กœ ์œ ์šฉํ•œ ๊ฐœ๋…์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋ช…๋ช…ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์„ ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋Š” ์ค‘๊ฐ„๊ฐ’์ด ๋‘ ๋ฒˆ ์ด์ƒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๋‹ค๋ฅธ ์–ธ์–ด์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, Lean์—์„œ ๋™์ผํ•œ ์ฝ”๋“œ๋ฅผ ๋‘ ๋ฒˆ ์ž‘์„ฑํ•˜๋ฉด ๋‘ ๋ฒˆ ๊ณ„์‚ฐ๋˜์ง€๋งŒ, ๊ฒฐ๊ณผ๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๋ฉด ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๊ฐ€ ์ €์žฅ๋˜์–ด ์žฌ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, unzip์€ ์Œ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฆฌ์ŠคํŠธ์˜ ์Œ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์Œ์˜ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด, unzip์˜ ๊ฒฐ๊ณผ๋Š” ๋นˆ ๋ฆฌ์ŠคํŠธ์˜ ์Œ์ž…๋‹ˆ๋‹ค. ์Œ์˜ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋จธ๋ฆฌ์— ์Œ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด, ๊ทธ ์Œ์˜ ๋‘ ํ•„๋“œ๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ unzipํ•œ ๊ฒฐ๊ณผ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด unzip์˜ ์ •์˜๋Š” ๊ทธ ์„ค๋ช…์„ ์ •ํ™•ํžˆ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. def unzip : List (ฮฑ ร— ฮฒ) โ†’ List ฮฑ ร— List ฮฒ | [] => ([], []) | (x, y) :: xys => (x :: (unzip xys).fst, y :: (unzip xys).snd) ๋ถˆํ–‰ํžˆ๋„, ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” ํ•„์š” ์ด์ƒ์œผ๋กœ ๋А๋ฆฝ๋‹ˆ๋‹ค. ์Œ์˜ ๋ฆฌ์ŠคํŠธ์— ์žˆ๋Š” ๊ฐ ํ•ญ๋ชฉ์€ ๋‘ ๋ฒˆ์˜ ์žฌ๊ท€ ํ˜ธ์ถœ๋กœ ์ด์–ด์ ธ, ์ด ํ•จ์ˆ˜๊ฐ€ ์ง€์ˆ˜ ์‹œ๊ฐ„์„ ์†Œ์š”ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‘ ์žฌ๊ท€ ํ˜ธ์ถœ์€ ๋ชจ๋‘ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋‚ผ ๊ฒƒ์ด๋ฏ€๋กœ, ์žฌ๊ท€ ํ˜ธ์ถœ์„ ๋‘ ๋ฒˆ ํ•  ์ด์œ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. Lean์—์„œ๋Š” let์„ ์‚ฌ์šฉํ•˜์—ฌ ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ช…๋ช…ํ•˜๊ณ  ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. let์„ ์‚ฌ์šฉํ•œ ์ง€์—ญ ์ •์˜๋Š” def๋ฅผ ์‚ฌ์šฉํ•œ ์ตœ์ƒ์œ„ ์ •์˜์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ง€์—ญ์ ์œผ๋กœ ์ •์˜๋  ์ด๋ฆ„, ์›ํ•œ๋‹ค๋ฉด ์ธ์ž, ํƒ€์ž… ์‹œ๊ทธ๋‹ˆ์ฒ˜, ๊ทธ๋ฆฌ๊ณ  := ๋’ค์— ์˜ค๋Š” ๋ณธ๋ฌธ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ง€์—ญ ์ •์˜ ํ›„, ํ•ด๋‹น ์ง€์—ญ ์ •์˜๊ฐ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ‘œํ˜„์‹(let ํ‘œํ˜„์‹์˜ ๋ณธ๋ฌธ)์€ let ํ‚ค์›Œ๋“œ์˜ ์—ด๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์—ด์—์„œ ์‹œ์ž‘ํ•˜๋Š” ์ƒˆ ์ค„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. unzip์—์„œ let์„ ์‚ฌ์šฉํ•œ ์ง€์—ญ ์ •์˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. def unzip : List (ฮฑ ร— ฮฒ) โ†’ List ฮฑ ร— List ฮฒ | [] => ([], []) | (x, y) :: xys => let unzipped : List ฮฑ ร— List ฮฒ := unzip xys (x :: unzipped.fst, y :: unzipped.snd) let์„ ํ•œ ์ค„์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, ์ง€์—ญ ์ •์˜์™€ ๋ณธ๋ฌธ์„ ์„ธ๋ฏธ์ฝœ๋ก ์œผ๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. let์„ ์‚ฌ์šฉํ•œ ์ง€์—ญ ์ •์˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ๋ชจ๋“  ์ผ€์ด์Šค๋ฅผ ํ•˜๋‚˜์˜ ํŒจํ„ด์œผ๋กœ ๋งค์นญํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ํŒจํ„ด ๋งค์นญ์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. unzip์˜ ๊ฒฝ์šฐ, ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๋Š” ์Œ์ž…๋‹ˆ๋‹ค. ์Œ์€ ๋‹จ ํ•˜๋‚˜์˜ ์ƒ์„ฑ์ž๋งŒ ๊ฐ€์ง€๋ฏ€๋กœ, unzipped๋ผ๋Š” ์ด๋ฆ„์„ ์Œ ํŒจํ„ด์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def unzip : List (ฮฑ ร— ฮฒ) โ†’ List ฮฑ ร— List ฮฒ | [] => ([], []) | (x, y) :: xys => let (xs, ys) : List ฮฑ ร— List ฮฒ := unzip xys (x :: xs, y :: ys) let๊ณผ ํ•จ๊ป˜ ํŒจํ„ด์„ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜๋ฉด, ์ ‘๊ทผ์ž ํ˜ธ์ถœ์„ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ฝ”๋“œ๋ฅผ ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. let๊ณผ def์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ ์žฌ๊ท€์ ์ธ let ์ •์˜๋Š” let rec์„ ์ž‘์„ฑํ•˜์—ฌ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฆฌ์ŠคํŠธ๋ฅผ ๋’ค์ง‘๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์žฌ๊ท€์ ์ธ ํ—ฌํผ ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. def reverse (xs : List ฮฑ) : List ฮฑ := let rec helper : List ฮฑ โ†’ List ฮฑ โ†’ List ฮฑ | [], soFar => soFar | y :: ys, soFar => helper ys (y :: soFar) helper xs [] ํ—ฌํผ ํ•จ์ˆ˜๋Š” ์ž…๋ ฅ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋”ฐ๋ผ ๋‚ด๋ ค๊ฐ€๋ฉด์„œ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ•ญ๋ชฉ์„ soFar๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค. ์ž…๋ ฅ ๋ฆฌ์ŠคํŠธ์˜ ๋์— ๋„๋‹ฌํ•˜๋ฉด, soFar๋Š” ์ž…๋ ฅ์˜ ๋’ค์ง‘ํžŒ ๋ฒ„์ „์„ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 1.7.4. ํƒ€์ž… ์ถ”๋ก  ๋งŽ์€ ์ƒํ™ฉ์—์„œ Lean์€ ํ‘œํ˜„์‹์˜ ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ, ๋ช…์‹œ์ ์ธ ํƒ€์ž…์€ ์ตœ์ƒ์œ„ ์ •์˜(def ์‚ฌ์šฉ)์™€ ์ง€์—ญ ์ •์˜(let ์‚ฌ์šฉ) ๋ชจ๋‘์—์„œ ์ƒ๋žต๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, unzip์— ๋Œ€ํ•œ ์žฌ๊ท€ ํ˜ธ์ถœ์€ ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. def unzip : List (ฮฑ ร— ฮฒ) โ†’ List ฮฑ ร— List ฮฒ | [] => ([], []) | (x, y) :: xys => let unzipped := unzip xys (x :: unzipped.fst, y :: unzipped.snd) ๊ฒฝํ—˜์ ์œผ๋กœ, ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž์™€ ๊ฐ™์€ ๋ฆฌํ„ฐ๋Ÿด ๊ฐ’์˜ ํƒ€์ž…์„ ์ƒ๋žตํ•˜๋Š” ๊ฒƒ์€ ๋ณดํ†ต ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ, Lean์ด ๋ฆฌํ„ฐ๋Ÿด ์ˆซ์ž์— ๋Œ€ํ•ด ์˜๋„ํ•œ ํƒ€์ž…๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lean์€ ํ•จ์ˆ˜ ์ ์šฉ์— ๋Œ€ํ•œ ํƒ€์ž…์„ ๋ณดํ†ต ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” ์ด๋ฏธ ์ธ์ž ํƒ€์ž…๊ณผ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ •์˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์ƒ๋žตํ•˜๋Š” ๊ฒƒ์€ ์ข…์ข… ์ž‘๋™ํ•˜์ง€๋งŒ, ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ œ์˜ unzipped์™€ ๊ฐ™์ด ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ์ •์˜๋Š”, ๊ทธ ๋ณธ๋ฌธ์ด ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์š” ์—†์œผ๋ฉฐ, ์ด ์ •์˜์˜ ๋ณธ๋ฌธ์€ ํ•จ์ˆ˜ ์ ์šฉ์ž…๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์ธ match ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•  ๋•Œ unzip์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์ƒ๋žตํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. def unzip (pairs : List (ฮฑ ร— ฮฒ)) := match pairs with | [] => ([], []) | (x, y) :: xys => let unzipped := unzip xys (x :: unzipped.fst, y :: unzipped.snd) ์ผ๋ฐ˜์ ์œผ๋กœ, ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์€ ์ ์€ ๊ฒƒ๋ณด๋‹ค ๋งŽ์€ ํŽธ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ฒซ์งธ, ๋ช…์‹œ์ ์ธ ํƒ€์ž…์€ ์ฝ”๋“œ์— ๋Œ€ํ•œ ๊ฐ€์ •์„ ๋…์ž์—๊ฒŒ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. Lean์ด ์Šค์Šค๋กœ ํƒ€์ž…์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋”๋ผ๋„, Lean์—๊ฒŒ ๋ฐ˜๋ณต์ ์œผ๋กœ ํƒ€์ž… ์ •๋ณด๋ฅผ ๋ฌป์ง€ ์•Š๊ณ  ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘˜์งธ, ๋ช…์‹œ์ ์ธ ํƒ€์ž…์€ ์˜ค๋ฅ˜๋ฅผ ๊ตญ์†Œํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์ด ํƒ€์ž…์— ๋Œ€ํ•ด ๋” ๋ช…์‹œ์ ์ผ์ˆ˜๋ก ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋” ์œ ์ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Lean๊ณผ ๊ฐ™์ด ๋งค์šฐ ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•œ ํƒ€์ž… ์‹œ์Šคํ…œ์„ ๊ฐ€์ง„ ์–ธ์–ด์—์„œ ํŠนํžˆ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์…‹์งธ, ๋ช…์‹œ์ ์ธ ํƒ€์ž…์€ ์• ์ดˆ์— ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํƒ€์ž…์€ ๋ช…์„ธ์ด๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ์˜ ํ”ผ๋“œ๋ฐฑ์€ ๋ช…์„ธ๋ฅผ ์ถฉ์กฑํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ์œ ์šฉํ•œ ๋„๊ตฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, Lean์˜ ํƒ€์ž… ์ถ”๋ก ์€ ์ตœ์„  ๋…ธ๋ ฅ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. Lean์˜ ํƒ€์ž… ์‹œ์Šคํ…œ์ด ๋งค์šฐ ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ชจ๋“  ํ‘œํ˜„์‹์— ๋Œ€ํ•ด "์ตœ๊ณ ์˜" ๋˜๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ํƒ€์ž…์„ ์ฐพ๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํƒ€์ž…์„ ์–ป๋”๋ผ๋„ ์ฃผ์–ด์ง„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋งž๋Š” ์˜ฌ๋ฐ”๋ฅธ ํƒ€์ž…์ด๋ผ๋Š” ๋ณด์žฅ์ด ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 14๋Š” Nat ๋˜๋Š” Int๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #check 1414 : Nat#check (14 : Int)14 : Int ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ˆ„๋ฝ๋˜๋ฉด ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. unzip ์ •์˜์—์„œ ๋ชจ๋“  ํƒ€์ž…์„ ์ƒ๋žตํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. def unzip pairs := match pairs with | [] => ([], []) | (x, y) :: xys => let unzipped := unzip xys (x :: unzipped.fst, y :: unzipped.snd) ์ด๋Š” match ํ‘œํ˜„์‹์— ๋Œ€ํ•œ ๋ฉ”์‹œ์ง€๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. Invalid match expression: This pattern contains metavariables: [] ์ด๋Š” match๊ฐ€ ๊ฒ€์‚ฌ๋˜๋Š” ๊ฐ’์˜ ํƒ€์ž…์„ ์•Œ์•„์•ผ ํ•˜์ง€๋งŒ, ๊ทธ ํƒ€์ž…์ด ์ œ๊ณต๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. "๋ฉ”ํƒ€๋ณ€์ˆ˜"๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์•Œ ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„์œผ๋กœ, ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์—์„œ๋Š” ?m.XYZ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ, ๋‹คํ˜•์„ฑ ์„น์…˜์—์„œ ์„ค๋ช…๋ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ์ธ์ž์— ๋Œ€ํ•œ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋žจ์กฐ์ฐจ๋„ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ•ญ๋“ฑ ํ•จ์ˆ˜๋Š” ์ „๋‹ฌ๋œ ์ธ์ž๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ž์™€ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. def id (x : ฮฑ) : ฮฑ := x Lean์€ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์Šค์Šค๋กœ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. def id (x : ฮฑ) := x ํ•˜์ง€๋งŒ ์ธ์ž ํƒ€์ž…์„ ์ƒ๋žตํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. def id x := xFailed to infer type of binder `x` ์ผ๋ฐ˜์ ์œผ๋กœ, "failed to infer"์™€ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋‚˜ ๋ฉ”ํƒ€๋ณ€์ˆ˜๋ฅผ ์–ธ๊ธ‰ํ•˜๋Š” ๋ฉ”์‹œ์ง€๋Š” ๋” ๋งŽ์€ ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์‹ ํ˜ธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ Lean์„ ๋ฐฐ์šฐ๋Š” ๋™์•ˆ์—๋Š” ๋Œ€๋ถ€๋ถ„์˜ ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. 1.7.5. ๋™์‹œ ๋งค์นญ ํŒจํ„ด ๋งค์นญ ํ‘œํ˜„์‹์€ ํŒจํ„ด ๋งค์นญ ์ •์˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—ฌ๋Ÿฌ ๊ฐ’์„ ํ•œ ๋ฒˆ์— ๋งค์นญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒ€์‚ฌํ•  ํ‘œํ˜„์‹๊ณผ ๊ทธ์— ๋Œ€์‘ํ•˜๋Š” ํŒจํ„ด ๋ชจ๋‘ ์ •์˜์— ์‚ฌ์šฉ๋œ ๊ตฌ๋ฌธ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋™์‹œ ๋งค์นญ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์˜ drop์ž…๋‹ˆ๋‹ค. def drop (n : Nat) (xs : List ฮฑ) : List ฮฑ := match n, xs with | Nat.zero, ys => ys | _, [] => [] | Nat.succ n , y :: ys => drop n ys ๋™์‹œ ๋งค์นญ์€ ์Œ์— ๋Œ€ํ•œ ๋งค์นญ๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ, ์ค‘์š”ํ•œ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. Lean์€ ๋งค์นญ๋˜๋Š” ํ‘œํ˜„์‹๊ณผ ํŒจํ„ด ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์„ ์ถ”์ ํ•˜๋ฉฐ, ์ด ์ •๋ณด๋Š” ์ข…๋ฃŒ ๊ฒ€์‚ฌ ๋ฐ ์ •์  ํƒ€์ž… ์ •๋ณด ์ „ํŒŒ์™€ ๊ฐ™์€ ๋ชฉ์ ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ, ์Œ์„ ๋งค์นญํ•˜๋Š” ๋ฐฉ์‹์˜ sameLength์€ ์ข…๋ฃŒ ๊ฒ€์‚ฌ๊ธฐ์— ์˜ํ•ด ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด xs์™€ x :: xs' ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์ด ์ค‘๊ฐ„์— ์žˆ๋Š” ์Œ์— ์˜ํ•ด ๊ฐ€๋ ค์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. def sameLength (xs : List ฮฑ) (ys : List ฮฒ) : Bool := match (xs, ys) with | ([], []) => true | (x :: xs', y :: ys') => sameLength xs' ys' | _ => falsefail to show termination for sameLengthwith errorsfailed to infer structural recursion:Not considering parameter ฮฑ of sameLength: it is unchanged in the recursive callsNot considering parameter ฮฒ of sameLength: it is unchanged in the recursive callsCannot use parameter xs: failed to eliminate recursive application sameLength xs' ys'Cannot use parameter ys: failed to eliminate recursive application sameLength xs' ys'Could not find a decreasing measure.The basic measures relate at each recursive call as follows:(<, โ‰ค, =: relation proved, ? all proofs failed, _: no proof attempted) xs ys1) 1816:28-46 ? ?Please use `termination_by` to specify a decreasing measure. ๋‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋™์‹œ์— ๋งค์นญํ•˜๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. def sameLength (xs : List ฮฑ) (ys : List ฮฒ) : Bool := match xs, ys with | [], [] => true | x :: xs', y :: ys' => sameLength xs' ys' | _, _ => false 1.7.6. ์ž์—ฐ์ˆ˜ ํŒจํ„ด ๋ฐ์ดํ„ฐ ํƒ€์ž…๊ณผ ํŒจํ„ด์— ๋Œ€ํ•œ ์„น์…˜์—์„œ, even์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค: def even (n : Nat) : Bool := match n with | Nat.zero => true | Nat.succ k => not (even k) List.cons์™€ List.nil์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฆฌ์ŠคํŠธ ํŒจํ„ด์„ ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ํŠน๋ณ„ํ•œ ๊ตฌ๋ฌธ์ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ž์—ฐ์ˆ˜๋„ ๋ฆฌํ„ฐ๋Ÿด ์ˆซ์ž์™€ +๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งค์นญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, even์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค: def even : Nat โ†’ Bool | 0 => true | n + 1 => not (even n) ์ด ํ‘œ๊ธฐ๋ฒ•์—์„œ + ํŒจํ„ด์˜ ์ธ์ž๋“ค์€ ์„œ๋กœ ๋‹ค๋ฅธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ ์™ผ์ชฝ ์ธ์ž(์œ„์˜ n)๋Š” ์—ฌ๋Ÿฌ Nat.succ ํŒจํ„ด์˜ ์ธ์ž๊ฐ€ ๋˜๊ณ , ์˜ค๋ฅธ์ชฝ ์ธ์ž(์œ„์˜ 1)๋Š” ํŒจํ„ด์„ ๊ฐ์Œ€ Nat.succ์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. Nat์„ 2๋กœ ๋‚˜๋ˆ„๊ณ  ๋‚˜๋จธ์ง€๋ฅผ ๋ฒ„๋ฆฌ๋Š” halve์˜ ๋ช…์‹œ์  ํŒจํ„ด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: def halve : Nat โ†’ Nat | Nat.zero => 0 | Nat.succ Nat.zero => 0 | Nat.succ (Nat.succ n) => halve n + 1 ์ด๋Š” ์ˆซ์ž ๋ฆฌํ„ฐ๋Ÿด๊ณผ +๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def halve : Nat โ†’ Nat | 0 => 0 | 1 => 0 | n + 2 => halve n + 1 ๋‚ด๋ถ€์ ์œผ๋กœ ๋‘ ์ •์˜๋Š” ์™„์ „ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์–ตํ•˜์„ธ์š”: halve n + 1์€ halve (n + 1)์ด ์•„๋‹ˆ๋ผ (halve n) + 1๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ๋•Œ, +์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š” ํ•ญ์ƒ ๋ฆฌํ„ฐ๋Ÿด Nat์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ง์…ˆ์€ ๊ตํ™˜ ๋ฒ•์น™์ด ์„ฑ๋ฆฝํ•˜์ง€๋งŒ, ํŒจํ„ด์—์„œ ์ธ์ž์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def halve : Nat โ†’ Nat | 0 => 0 | 1 => 0 | 2 + n => halve n + 1Invalid pattern(s): `n` is an explicit pattern variable, but it only occurs in positions that are inaccessible to pattern matching: .(Nat.add 2 n) ์ด ์ œ์•ฝ ๋•๋ถ„์— Lean์€ ํŒจํ„ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  + ํ‘œ๊ธฐ๋ฒ•์„ ๋‚ด๋ถ€์ ์ธ Nat.succ ์‚ฌ์šฉ์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์–ธ์–ด์˜ ๋‚ด๋ถ€๋ฅผ ๋” ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•ด ์ค๋‹ˆ๋‹ค. 1.7.7. ์ต๋ช… ํ•จ์ˆ˜ Lean์˜ ํ•จ์ˆ˜๋Š” ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ์ •์˜๋  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํ‘œํ˜„์‹์œผ๋กœ์„œ์˜ ํ•จ์ˆ˜๋Š” fun ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ํ‘œํ˜„์‹์€ fun ํ‚ค์›Œ๋“œ๋กœ ์‹œ์ž‘ํ•˜๋ฉฐ, ํ•˜๋‚˜ ์ด์ƒ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋’ค๋”ฐ๋ฅด๊ณ , =>๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜ํ™˜ ํ‘œํ˜„์‹๊ณผ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ˆซ์ž์— 1์„ ๋”ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: #check fun x => x + 1fun x => x + 1 : Nat โ†’ Nat ํƒ€์ž… ์ฃผ์„์€ def์—์„œ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ด„ํ˜ธ์™€ ์ฝœ๋ก ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค: #check fun (x : Int) => x + 1fun x => x + 1 : Int โ†’ Int ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์•”์‹œ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: #check fun {ฮฑ : Type} (x : ฮฑ) => xfun {ฮฑ} x => x : {ฮฑ : Type} โ†’ ฮฑ โ†’ ฮฑ ์ด๋Ÿฌํ•œ ์Šคํƒ€์ผ์˜ ์ต๋ช… ํ•จ์ˆ˜ ํ‘œํ˜„์‹์€ ์ข…์ข… ๋žŒ๋‹ค ํ‘œํ˜„์‹์ด๋ผ๊ณ  ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค. ์ด๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ ์ˆ˜ํ•™์  ์„ค๋ช…์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ํ‘œ๊ธฐ๋ฒ•์ด Lean์˜ fun ํ‚ค์›Œ๋“œ ์ž๋ฆฌ์— ๊ทธ๋ฆฌ์Šค ๋ฌธ์ž ฮป(๋žŒ๋‹ค)๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Lean์ด fun ๋Œ€์‹  ฮป๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๊ธด ํ•˜์ง€๋งŒ, fun์„ ์“ฐ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ์ต๋ช… ํ•จ์ˆ˜๋Š” def์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋‹ค์ค‘ ํŒจํ„ด ์Šคํƒ€์ผ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ž์—ฐ์ˆ˜์˜ ์ด์ „ ์ˆ˜๋ฅผ (์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ) ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: #check fun | 0 => none | n + 1 => some nfun x => match x with | 0 => none | n.succ => some n : Nat โ†’ Option Nat Lean์ด ํ•จ์ˆ˜๋ฅผ ์„ค๋ช…ํ•  ๋•Œ ์ด๋ฆ„ ์žˆ๋Š” ์ธ์ž์™€ match ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. Lean์˜ ํŽธ๋ฆฌํ•œ ๊ตฌ๋ฌธ์  ์ถ•์•ฝํ˜• ์ค‘ ๋‹ค์ˆ˜๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋” ๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ์œผ๋กœ ํ™•์žฅ๋˜๋ฉฐ, ๋•Œ๋กœ๋Š” ์ด๋Ÿฌํ•œ ์ถ”์ƒํ™”๊ฐ€ ๋“œ๋Ÿฌ๋‚˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ž๋ฅผ ๋ฐ›๋Š” def๋ฅผ ์‚ฌ์šฉํ•œ ์ •์˜๋Š” ํ•จ์ˆ˜ ํ‘œํ˜„์‹์œผ๋กœ ๋‹ค์‹œ ์ž‘์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ธ์ž๋ฅผ ๋‘ ๋ฐฐ๋กœ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def double : Nat โ†’ Nat := fun | 0 => 0 | k + 1 => double k + 2 fun x => x + 1๊ณผ ๊ฐ™์ด ์ต๋ช… ํ•จ์ˆ˜๊ฐ€ ๋งค์šฐ ๊ฐ„๋‹จํ•  ๋•Œ, ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ๊ตฌ๋ฌธ์€ ์ƒ๋‹นํžˆ ์žฅํ™ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŠน์ • ์˜ˆ์—์„œ๋Š” ํ•จ์ˆ˜๋ฅผ ๋„์ž…ํ•˜๋Š” ๋ฐ 6๊ฐœ์˜ ๊ณต๋ฐฑ์ด ์•„๋‹Œ ๋ฌธ์ž๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ๊ณ , ๋ณธ๋ฌธ์€ 3๊ฐœ์˜ ๊ณต๋ฐฑ์ด ์•„๋‹Œ ๋ฌธ์ž๋กœ๋งŒ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด Lean์€ ์ถ•์•ฝํ˜•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ด„ํ˜ธ๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ํ‘œํ˜„์‹์—์„œ ยท(MIDDLE DOT)๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ด„ํ˜ธ ์•ˆ์˜ ํ‘œํ˜„์‹์€ ํ•จ์ˆ˜์˜ ๋ณธ๋ฌธ์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ํŠน์ • ํ•จ์ˆ˜๋Š” (ยท + 1)๋กœ๋„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ยท์€ ํ•ญ์ƒ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ด„ํ˜ธ ์„ธํŠธ๋กœ๋ถ€ํ„ฐ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, (ยท + 5, 3)์€ ์ˆซ์ž ์Œ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ธ ๋ฐ˜๋ฉด, ((ยท + 5), 3)์€ ํ•จ์ˆ˜์™€ ์ˆซ์ž๋กœ ์ด๋ฃจ์–ด์ง„ ์Œ์ž…๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ ์ด ์‚ฌ์šฉ๋˜๋ฉด ์™ผ์ชฝ์—์„œ ์˜ค๋ฅธ์ชฝ ์ˆœ์„œ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค: (ยท , ยท) 1 2(1, ยท) 2(1, 2) ์ต๋ช… ํ•จ์ˆ˜๋Š” def๋‚˜ let์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜๋œ ํ•จ์ˆ˜์™€ ์ •ํ™•ํžˆ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #eval (fun x => x + x) 5 ๋ช…๋ น์–ด๋Š” ๋‹ค์Œ์„ ๊ฒฐ๊ณผ๋กœ ๋ƒ…๋‹ˆ๋‹ค: 10 ๋ฐ˜๋ฉด #eval (ยท * 2) 5๋Š” ๋‹ค์Œ์„ ๊ฒฐ๊ณผ๋กœ ๋ƒ…๋‹ˆ๋‹ค: 10 1.7.8. ๋„ค์ž„์ŠคํŽ˜์ด์Šค Lean์˜ ๊ฐ ์ด๋ฆ„์€ ์ด๋ฆ„์˜ ๋ชจ์Œ์ธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์•ˆ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฆ„์€ .์„ ์‚ฌ์šฉํ•˜์—ฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋ฐฐ์น˜๋˜๋ฏ€๋กœ, List.map์€ List ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ๋Š” map์ด๋ผ๋Š” ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ๋Š” ์ด๋ฆ„๋“ค์€ ๋‹ค๋ฅธ ๋ถ€๋ถ„์ด ๋™์ผํ•˜๋”๋ผ๋„ ์„œ๋กœ ์ถฉ๋Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” List.map๊ณผ Array.map์ด ๋‹ค๋ฅธ ์ด๋ฆ„์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ์ค‘์ฒฉ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, Project.Frontend.User.loginTime์€ ์ค‘์ฒฉ๋œ Project.Frontend.User ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ๋Š” loginTime์ด๋ผ๋Š” ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์ด๋ฆ„์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋‚ด์—์„œ ์ง์ ‘ ์ •์˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, double์ด๋ผ๋Š” ์ด๋ฆ„์€ Nat ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def Nat.double (x : Nat) : Nat := x + x Nat์€ ํƒ€์ž…์˜ ์ด๋ฆ„์ด๊ธฐ๋„ ํ•˜๋ฏ€๋กœ, Nat ํƒ€์ž…์˜ ํ‘œํ˜„์‹์— Nat.double์„ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด ์  ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: #eval (4 : Nat).double8 ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ง์ ‘ ์ด๋ฆ„์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„, namespace์™€ end ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ จ์˜ ์„ ์–ธ๋“ค์„ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ์€ NewNamespace๋ผ๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— triple๊ณผ quadruple์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค: namespace NewNamespacedef triple (x : Nat) : Nat := 3 * xdef quadruple (x : Nat) : Nat := 2 * x + 2 * xend NewNamespace ์ด๋“ค์„ ์ฐธ์กฐํ•˜๋ ค๋ฉด ์ด๋ฆ„ ์•ž์— NewNamespace.๋ฅผ ๋ถ™์ž…๋‹ˆ๋‹ค: #check NewNamespace.tripleNewNamespace.triple (x : Nat) : Nat#check NewNamespace.quadrupleNewNamespace.quadruple (x : Nat) : Nat ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” openํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์•ˆ์˜ ์ด๋ฆ„๋“ค์„ ๋ช…์‹œ์ ์ธ ํ•œ์ •์ž ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‘œํ˜„์‹ ์•ž์— open MyNamespace in์„ ์ž‘์„ฑํ•˜๋ฉด MyNamespace์˜ ๋‚ด์šฉ์ด ํ•ด๋‹น ํ‘œํ˜„์‹์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, timesTwelve๋Š” NewNamespace๋ฅผ ์—ฐ ํ›„์— quadruple๊ณผ triple์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค: def timesTwelve (x : Nat) := open NewNamespace in quadruple (triple x) ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ๋ช…๋ น์–ด ์•ž์—์„œ๋„ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋‹จ์ผ ํ‘œํ˜„์‹๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ช…๋ น์–ด์˜ ๋ชจ๋“  ๋ถ€๋ถ„์—์„œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๋‚ด์šฉ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ๋ช…๋ น์–ด ์•ž์— open ... in์„ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. open NewNamespace in#check quadrupleNewNamespace.quadruple (x : Nat) : Nat ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” ์ด๋ฆ„์˜ ์ „์ฒด ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ํŒŒ์ผ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ดํ›„์˜ ๋ชจ๋“  ๋ช…๋ น์–ด์— ๋Œ€ํ•ด ์ถ”๊ฐ€์ ์œผ๋กœ ์—ด๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ open์„ ์‚ฌ์šฉํ•  ๋•Œ in์„ ์ƒ๋žตํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 1.7.9. if let ํ•ฉ ํƒ€์ž…์„ ๊ฐ–๋Š” ๊ฐ’์„ ์‚ฌ์šฉํ•  ๋•Œ, ์ข…์ข… ๋‹จ ํ•˜๋‚˜์˜ ์ƒ์„ฑ์ž์—๋งŒ ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋งˆํฌ๋‹ค์šด ์ธ๋ผ์ธ ์š”์†Œ์˜ ์ผ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋‹ค์Œ ํƒ€์ž…์ด ์ฃผ์–ด์กŒ์„ ๋•Œ: inductive Inline : Type where | lineBreak | string : String โ†’ Inline | emph : Inline โ†’ Inline | strong : Inline โ†’ Inline ๋ฌธ์ž์—ด ์š”์†Œ๋ฅผ ์ธ์‹ํ•˜๊ณ  ๊ทธ ๋‚ด์šฉ์„ ์ถ”์ถœํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: def Inline.string? (inline : Inline) : Option String := match inline with | Inline.string s => some s | _ => none ์ด ํ•จ์ˆ˜์˜ ๋ณธ๋ฌธ์„ ์ž‘์„ฑํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ if์™€ let์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค: def Inline.string? (inline : Inline) : Option String := if let Inline.string s := inline then some s else none ์ด๊ฒƒ์€ ํŒจํ„ด ๋งค์นญ let ๊ตฌ๋ฌธ๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ฐจ์ด์ ์€ else ๊ฒฝ์šฐ์— ๋Œ€์ฒด ๋ฐฉ์•ˆ์ด ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ฉ ํƒ€์ž…๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ฌธ๋งฅ์—์„œ๋Š” match ๋Œ€์‹  if let์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1.7.10. ์œ„์น˜ ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ์ฒด ์ธ์ž ๊ตฌ์กฐ์ฒด์— ๋Œ€ํ•œ ์„น์…˜์—์„œ๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค: Point.mk 1 2 ๊ฐ™์€ ์ƒ์„ฑ์ž ์ง์ ‘ ํ˜ธ์ถœ. { x := 1, y := 2 } ๊ฐ™์€ ์ค‘๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•. ์–ด๋–ค ๋ฌธ๋งฅ์—์„œ๋Š” ์ƒ์„ฑ์ž๋ฅผ ์ง์ ‘ ๋ช…๋ช…ํ•˜์ง€ ์•Š๊ณ , ์ด๋ฆ„ ๋Œ€์‹  ์œ„์น˜์— ๋”ฐ๋ผ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์–‘ํ•œ ์œ ์‚ฌํ•œ ๊ตฌ์กฐ์ฒด ํƒ€์ž…์„ ์ •์˜ํ•˜๋ฉด ๋„๋ฉ”์ธ ๊ฐœ๋…์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ฝ”๋“œ๋ฅผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ฝ๋Š” ๋ฐฉ์‹์€ ๊ฐ๊ฐ์„ ๋ณธ์งˆ์ ์œผ๋กœ ํŠœํ”Œ๋กœ ์ทจ๊ธ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ๋งฅ์—์„œ๋Š” ์ธ์ž๋ฅผ ๊บพ์‡ ๊ด„ํ˜ธ โŸจ์™€ โŸฉ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Point๋Š” โŸจ1, 2โŸฉ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐ์‹ฌํ•˜์„ธ์š”! ์ด ๊ด„ํ˜ธ๋“ค์€ ๋ถ€๋“ฑํ˜ธ <์™€ >์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๋‹ค๋ฅธ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค. ๊ฐ๊ฐ \<์™€ \>๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„ ์žˆ๋Š” ์ƒ์„ฑ์ž ์ธ์ž๋ฅผ ์œ„ํ•œ ์ค‘๊ด„ํ˜ธ ํ‘œ๊ธฐ๋ฒ•๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ด ์œ„์น˜ ๊ธฐ๋ฐ˜ ๊ตฌ๋ฌธ์€ Lean์ด ํƒ€์ž… ์ฃผ์„์ด๋‚˜ ํ”„๋กœ๊ทธ๋žจ์˜ ๋‹ค๋ฅธ ํƒ€์ž… ์ •๋ณด๋กœ๋ถ€ํ„ฐ ๊ตฌ์กฐ์ฒด์˜ ํƒ€์ž…์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ๋งฅ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, #eval โŸจ1, 2โŸฉ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค: Invalid `โŸจ...โŸฉ` notation: The expected type of this term could not be determined ์ด ์˜ค๋ฅ˜๋Š” ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํƒ€์ž… ์ •๋ณด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. #eval (โŸจ1, 2โŸฉ : Point)์™€ ๊ฐ™์ด ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค: { x := 1.000000, y := 2.000000 } 1.7.11. ๋ฌธ์ž์—ด ๋ณด๊ฐ„ Lean์—์„œ ๋ฌธ์ž์—ด ์•ž์— s!๋ฅผ ๋ถ™์ด๋ฉด ๋ณด๊ฐ„์ด ํ™œ์„ฑํ™”๋˜์–ด, ๋ฌธ์ž์—ด ์•ˆ์˜ ์ค‘๊ด„ํ˜ธ์— ํฌํ•จ๋œ ํ‘œํ˜„์‹์ด ๊ทธ ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํŒŒ์ด์ฌ์˜ f-string์ด๋‚˜ C# ์˜ $-์ ‘๋‘์‚ฌ ๋ฌธ์ž์—ด๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, #eval s!"three fives is {NewNamespace.triple 5}" ๋Š” ๋‹ค์Œ์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค: "three fives is 15" ๋ชจ๋“  ํ‘œํ˜„์‹์ด ๋ฌธ์ž์—ด์— ๋ณด๊ฐ„๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ•จ์ˆ˜๋ฅผ ๋ณด๊ฐ„ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. #check s!"three fives is {NewNamespace.triple}" ๋Š” ๋‹ค์Œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค: failed to synthesize ToString (Nat โ†’ Nat)Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command. ์ด๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ‘œ์ค€์ ์ธ ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ ํ‘œํ˜„์‹ ํ‰๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ํ…Œ์ด๋ธ”์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ํ…Œ์ด๋ธ”์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. failed to synthesize instance๋ผ๋Š” ๋ฉ”์‹œ์ง€๋Š” Lean ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฃผ์–ด์ง„ ํƒ€์ž…์— ๋Œ€ํ•ด ์ด ํ…Œ์ด๋ธ”์—์„œ ํ•ญ๋ชฉ์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž… ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์žฅ์—์„œ๋Š” ํ…Œ์ด๋ธ”์— ์ƒˆ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํฌํ•จํ•˜์—ฌ ์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. 1.8. ์š”์•ฝ 1.8.1. ํ‘œํ˜„์‹ ํ‰๊ฐ€ Lean์—์„œ ๊ณ„์‚ฐ์€ ํ‘œํ˜„์‹์ด ํ‰๊ฐ€๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ฐ˜์ ์ธ ์ˆ˜ํ•™ ํ‘œํ˜„์‹์˜ ๊ทœ์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ฆ‰, ์ „์ฒด ํ‘œํ˜„์‹์ด ๊ฐ’์ด ๋  ๋•Œ๊นŒ์ง€ ํ•˜์œ„ ํ‘œํ˜„์‹์€ ์ผ๋ฐ˜์ ์ธ ์—ฐ์‚ฐ ์ˆœ์„œ์— ๋”ฐ๋ผ ํ•ด๋‹น ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. if๋‚˜ match๋ฅผ ํ‰๊ฐ€ํ•  ๋•Œ, ์กฐ๊ฑด์ด๋‚˜ match ๋Œ€์ƒ์˜ ๊ฐ’์ด ๋ฐœ๊ฒฌ๋  ๋•Œ๊นŒ์ง€ ๋ถ„๊ธฐ ๋‚ด์˜ ํ‘œํ˜„์‹์€ ํ‰๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณ€์ˆ˜๋Š” ์ผ๋‹จ ๊ฐ’์„ ํ• ๋‹น๋ฐ›์œผ๋ฉด ์ ˆ๋Œ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ˆ˜ํ•™๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์™€๋Š” ๋‹ฌ๋ฆฌ, Lean์˜ ๋ณ€์ˆ˜๋Š” ์ƒˆ๋กœ์šด ๊ฐ’์„ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ฃผ์†Œ๋ผ๊ธฐ๋ณด๋‹ค๋Š” ๋‹จ์ˆœํžˆ ๊ฐ’์„ ์œ„ํ•œ ์ž๋ฆฌ ํ‘œ์‹œ์ž์ž…๋‹ˆ๋‹ค. ๋ณ€์ˆ˜์˜ ๊ฐ’์€ def๋ฅผ ์‚ฌ์šฉํ•œ ์ „์—ญ ์ •์˜, let์„ ์‚ฌ์šฉํ•œ ์ง€์—ญ ์ •์˜, ํ•จ์ˆ˜์˜ ๋ช…๋ช…๋œ ์ธ์ˆ˜ ๋˜๋Š” ํŒจํ„ด ๋งค์นญ์—์„œ ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1.8.2. ํ•จ์ˆ˜ Lean์—์„œ ํ•จ์ˆ˜๋Š” ์ผ๊ธ‰ ๊ฐ’์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋˜๊ฑฐ๋‚˜, ๋ณ€์ˆ˜์— ์ €์žฅ๋˜๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ๊ฐ’์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  Lean ํ•จ์ˆ˜๋Š” ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๋‘˜ ์ด์ƒ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•ด Lean์€ ์ปค๋ง(currying)์ด๋ผ๋Š” ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜๋ฉด ๋‚˜๋จธ์ง€ ์ธ์ˆ˜๋ฅผ ๊ธฐ๋Œ€ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ˆ˜๋ฅผ ๋ฐ›์ง€ ์•Š๋Š” ํ•จ์ˆ˜๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๊ธฐ ์œ„ํ•ด Lean์€ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ์ •๋ณด๊ฐ€ ์ ์€ ์ธ์ˆ˜์ธ Unit ํƒ€์ž…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“œ๋Š” ์ฃผ์š” ๋ฐฉ๋ฒ•์€ ์„ธ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ต๋ช… ํ•จ์ˆ˜๋Š” fun์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Point์˜ ํ•„๋“œ๋ฅผ ๋ฐ”๊พธ๋Š” ํ•จ์ˆ˜๋Š” fun (point : Point) => { x := point.y, y := point.x : Point }์™€ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ„๋‹จํ•œ ์ต๋ช… ํ•จ์ˆ˜๋Š” ๊ด„ํ˜ธ ์•ˆ์— ํ•˜๋‚˜ ์ด์ƒ์˜ ยท์„ ๋ฐฐ์น˜ํ•˜์—ฌ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ๊ฐ€์šด๋ฐ ์ ์€ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๊ฐ€ ๋˜๊ณ , ๊ด„ํ˜ธ๋Š” ํ•จ์ˆ˜์˜ ๋ณธ๋ฌธ์„ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ธ์ˆ˜์—์„œ 1์„ ๋นผ๋Š” ํ•จ์ˆ˜๋Š” fun x => x - 1 ๋Œ€์‹  (ยท - 1)๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ์ธ์ˆ˜ ๋ชฉ๋ก์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ํŒจํ„ด ๋งค์นญ ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ def ๋˜๋Š” let์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1.8.3. ํƒ€์ž… Lean์€ ๋ชจ๋“  ํ‘œํ˜„์‹์— ํƒ€์ž…์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. Int, Point, {ฮฑ : Type} โ†’ Nat โ†’ ฮฑ โ†’ List ฮฑ, ๊ทธ๋ฆฌ๊ณ  Option (String โŠ• (Nat ร— String))๊ณผ ๊ฐ™์€ ํƒ€์ž…์€ ํ‘œํ˜„์‹์— ๋Œ€ํ•ด ์ตœ์ข…์ ์œผ๋กœ ๋ฐœ๊ฒฌ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์–ธ์–ด์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Lean์˜ ํƒ€์ž…์€ Lean ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ํ™•์ธ๋˜๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฐ€๋ฒผ์šด ๋ช…์„ธ๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์–ด, ํŠน์ • ์ข…๋ฅ˜์˜ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ•„์š”์„ฑ์„ ์—†์• ์ค๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด์™€ ๋‹ฌ๋ฆฌ, Lean์˜ ํƒ€์ž…์€ ์ž„์˜์˜ ์ˆ˜ํ•™๋„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ์ •๋ฆฌ ์ฆ๋ช…์˜ ์„ธ๊ณ„๋ฅผ ํ†ตํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฑ…์—์„œ๋Š” ์ •๋ฆฌ ์ฆ๋ช…์„ ์œ„ํ•ด Lean์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋Œ€๋ถ€๋ถ„ ๋‹ค๋ฃจ์ง€ ์•Š์ง€๋งŒ, Theorem Proving in Lean 4์—์„œ ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ํ‘œํ˜„์‹์—๋Š” ์—ฌ๋Ÿฌ ํƒ€์ž…์ด ์ฃผ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 3์€ Int ๋˜๋Š” Nat๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lean์—์„œ๋Š” ์ด๋ฅผ ๊ฐ™์€ ๊ฒƒ์— ๋Œ€ํ•œ ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ, ์šฐ์—ฐํžˆ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑ๋œ, ํ•˜๋‚˜๋Š” Nat ํƒ€์ž…์ด๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” Int ํƒ€์ž…์ธ ๋‘ ๊ฐœ์˜ ๋ณ„๋„ ํ‘œํ˜„์‹์œผ๋กœ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Lean์€ ๋•Œ๋•Œ๋กœ ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ข…์ข… ์‚ฌ์šฉ์ž๊ฐ€ ํƒ€์ž…์„ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Lean์˜ ํƒ€์ž… ์‹œ์Šคํ…œ์ด ๋งค์šฐ ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Lean์ด ํƒ€์ž…์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋”๋ผ๋„ ์›ํ•˜๋Š” ํƒ€์ž…์„ ์ฐพ์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 3์€ Int๋กœ ์‚ฌ์šฉ๋  ์˜๋„์˜€์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ถ”๊ฐ€์ ์ธ ์ œ์•ฝ ์กฐ๊ฑด์ด ์—†๋‹ค๋ฉด Lean์€ Nat ํƒ€์ž…์„ ๋ถ€์—ฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ, ๋Œ€๋ถ€๋ถ„์˜ ํƒ€์ž…์€ ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์„ฑํ•˜๊ณ , ์•„์ฃผ ๋ช…๋ฐฑํ•œ ํƒ€์ž…๋งŒ Lean์ด ์ฑ„์šฐ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋Š” Lean์˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐœ์„ ํ•˜๊ณ  ํ”„๋กœ๊ทธ๋ž˜๋จธ์˜ ์˜๋„๋ฅผ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ํ•จ์ˆ˜๋‚˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ํƒ€์ž…์„ ์ธ์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ํŠน์„ฑ์„ ๋‹คํ˜•์„ฑ(polymorphic)์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋‹คํ˜•์„ฑ์€ ๋ฆฌ์ŠคํŠธ์˜ ํ•ญ๋ชฉ ํƒ€์ž…์— ์ƒ๊ด€์—†์ด ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. Lean์—์„œ๋Š” ํƒ€์ž…์ด ์ผ๊ธ‰ ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹คํ˜•์„ฑ์€ ํŠน๋ณ„ํ•œ ๊ตฌ๋ฌธ์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ํƒ€์ž…์€ ๋‹ค๋ฅธ ์ธ์ˆ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ํƒ€์ž…์—์„œ ์ธ์ˆ˜์— ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋ฉด ๋‚˜์ค‘์˜ ํƒ€์ž…์—์„œ ๊ทธ ์ด๋ฆ„์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•จ์ˆ˜๊ฐ€ ์ธ์ˆ˜์— ์ ์šฉ๋  ๋•Œ ๊ฒฐ๊ณผ ํ•ญ์˜ ํƒ€์ž…์€ ์ธ์ˆ˜์˜ ์ด๋ฆ„์ด ์ ์šฉ๋œ ์‹ค์ œ ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋˜์–ด ์ฐพ์•„์ง‘๋‹ˆ๋‹ค. 1.8.4. ๊ตฌ์กฐ์ฒด์™€ ๊ท€๋‚ฉ์  ํƒ€์ž… structure ๋˜๋Š” inductive ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ Lean์— ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ํƒ€์ž…์€ ์ •์˜๊ฐ€ ๋™์ผํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์–ด๋–ค ํƒ€์ž…๊ณผ๋„ ๋™๋“ฑํ•˜๋‹ค๊ณ  ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ํƒ€์ž…์—๋Š” ํ•ด๋‹น ๊ฐ’๋“ค์ด ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์žˆ์œผ๋ฉฐ, ๊ฐ ์ƒ์„ฑ์ž๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. Lean์˜ ์ƒ์„ฑ์ž๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด์˜ ์ƒ์„ฑ์ž์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Lean์˜ ์ƒ์„ฑ์ž๋Š” ํ• ๋‹น๋œ ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋Šฅ๋™์ ์ธ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ, ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๋น„ํ™œ์„ฑ ํ™€๋”์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ structure๋Š” ๊ณฑ ํƒ€์ž…(์ฆ‰, ์—ฌ๋Ÿฌ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ๋‹จ ํ•˜๋‚˜์˜ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง„ ํƒ€์ž…)์„ ๋„์ž…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ณ , inductive๋Š” ํ•ฉ ํƒ€์ž…(์ฆ‰, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ณ ์œ ํ•œ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง„ ํƒ€์ž…)์„ ๋„์ž…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. structure๋กœ ์ •์˜๋œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์—๋Š” ๊ฐ ํ•„๋“œ์— ๋Œ€ํ•œ ์ ‘๊ทผ์ž ํ•จ์ˆ˜๊ฐ€ ํ•˜๋‚˜์”ฉ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์กฐ์ฒด์™€ ๊ท€๋‚ฉ์  ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋ชจ๋‘ ํŒจํ„ด ๋งค์นญ์œผ๋กœ ์†Œ๋น„๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ํ•ด๋‹น ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ๊ตฌ๋ฌธ์˜ ์ผ๋ถ€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ์ž ๋‚ด๋ถ€์— ์ €์žฅ๋œ ๊ฐ’์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ํŒจํ„ด ๋งค์นญ์€ ๊ฐ’์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์•„๋Š” ๊ฒƒ์ด ๊ณง ๊ทธ ๊ฐ’์„ ์†Œ๋น„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•„๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. 1.8.5. ์žฌ๊ท€ ์žฌ๊ท€์ ์ด๋ผ๋Š” ๋ง์€ ์ •์˜๋˜๋Š” ์ด๋ฆ„์ด ์ •์˜ ์ž์ฒด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์„ ๋œปํ•ฉ๋‹ˆ๋‹ค. Lean์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ผ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋Œ€ํ™”ํ˜• ์ •๋ฆฌ ์ฆ๋ช…๊ธฐ์ด๊ธฐ๋„ ํ•˜๋ฏ€๋กœ, ์žฌ๊ท€์  ์ •์˜์—๋Š” ํŠน์ • ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค. Lean์˜ ๋…ผ๋ฆฌ์  ์ธก๋ฉด์—์„œ ์ˆœํ™˜ ์ •์˜๋Š” ๋…ผ๋ฆฌ์  ๋น„์ผ๊ด€์„ฑ์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์žฌ๊ท€์  ์ •์˜๊ฐ€ Lean์˜ ๋…ผ๋ฆฌ์  ์ธก๋ฉด์„ ํ›ผ์†ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด, Lean์€ ๋ชจ๋“  ์žฌ๊ท€ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ค ์ธ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜๋“  ์ข…๋ฃŒ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ์ด๋Š” ์žฌ๊ท€ ํ˜ธ์ถœ์ด ๋ชจ๋‘ ์ž…๋ ฅ์˜ ๊ตฌ์กฐ์ ์œผ๋กœ ๋” ์ž‘์€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ˆ˜ํ–‰๋˜์–ด ํ•ญ์ƒ ๊ธฐ๋ณธ ์‚ฌ๋ก€(base case)๋กœ์˜ ์ง„ํ–‰์„ ๋ณด์žฅํ•˜๊ฑฐ๋‚˜, ์‚ฌ์šฉ์ž๊ฐ€ ํ•จ์ˆ˜๊ฐ€ ํ•ญ์ƒ ์ข…๋ฃŒ๋œ๋‹ค๋Š” ๋‹ค๋ฅธ ์ฆ๊ฑฐ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์žฌ๊ท€์  ๊ท€๋‚ฉ์  ํƒ€์ž…์€ ํ•ด๋‹น ํƒ€์ž…์˜ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜๋ฅผ ์ธ์ฝ”๋”ฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

hackers.pub ยท Hackers' Pub

Link author: ์ดˆ๋ฌด@2chanhaeng@hackers.pub

1

RE: social.wake.st/@liaizon/116085

It is a good strategy, but more importantly, it gives people the agency to choose what platforms and protocols they want to use while still finding the communities they need to.

I wrote about it a couple years ago: augment.ink/bridges-the-last-n

0

I wish the best, but still rocks:

> If deployed on a 16 GB RAM machine with at least 4 cores, a single ejabberd node can typically handle 200-300 K online users.

From: docs.ejabberd.im/get-started/

My 17 years old server is on 8GiB RAM with four 1.2GHz cores. I don't notice it. User data takes up 200MiB of space (it massively increased recently for some reason). Unlike Synapse :)

0

I wish the best, but still rocks:

> If deployed on a 16 GB RAM machine with at least 4 cores, a single ejabberd node can typically handle 200-300 K online users.

From: docs.ejabberd.im/get-started/

My 17 years old server is on 8GiB RAM with four 1.2GHz cores. I don't notice it. User data takes up 200MiB of space (it massively increased recently for some reason). Unlike Synapse :)

0
0
๋ณธ์ธ๋ณด๋‹ค ํ’์š”๋กœ์šด ์‚ถ์—์„œ ๋‹ค์–‘ํ•œ ์Œ์‹์„ ์ฆ๊ธฐ๋Š”๊ฒŒ ์กฐ์ƒ๋‹˜์˜ ์†Œ์›์ด์…จ์œผ๋‹ˆ(์•„๋‹Œ ๋ถ„๋„ ๊ณ„์‹œ๊ฒ ์ง€) ๋‘์ซ€๊พธ๋ฅผ ์˜ฌ๋ ค ์กฐ์ƒ๋‹˜์˜ ์ธ์ƒ์ด ํ—›๋˜์ง€ ์•Š์•˜์Œ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ ๋งŒํผ ํฐ ํšจ๋„๊ฐ€ ์–ด๋””์žˆ๋‚˜?
0

Opoziฤnรญ politici kritizujรญ vรฝsledek jednรกnรญ snฤ›movnรญho mandรกtovรฉho a imunitnรญho vรฝboru, kterรฝ nedoporuฤil vydat k trestnรญmu stรญhรกnรญ Andreje Babiลกe a Tomia Okamuru.
โ„น Dolnรญ komora by o tom mฤ›la rozhodovat na mimoล™รกdnรฉ schลฏzi 5. bล™ezna. Premiรฉr mรก jรญt znovu k soudu kvลฏli dotaci na areรกl ฤŒapรญ hnรญzdo. ล รฉf snฤ›movny pak ฤelรญ stรญhรกnรญ v souvislosti s pล™รญpadem pล™edloลˆskรฝch plakรกtลฏ SPD pล™ed senรกtnรญmi a krajskรฝmi volbami.

0
0
0
0

ใƒ•ใ‚ฉใƒญใƒฏใƒผใ•ใ‚“ใŒ300ไบบ่ถ…ใˆใŸใ—ใ€ๅนดๅค‰ใ‚ใฃใŸใ‹ใ‚‰ใƒžใƒชใƒผใซ้ ผใ‚“ใงใƒ‘ใƒณใƒ„ใ‚’่ฆ‹ใ›ใฆใ‚‚ใ‚‰ใ„ใพใ—ใŸ

1

ๆดช ๆฐ‘ๆ†™ (Hong Minhee) shared the below article:

Functional Programming in Lean ํ•œ๊ตญ์–ด ๋ฒˆ์—ญ - 1. Lean ์•Œ์•„๋ณด๊ธฐ

์ดˆ๋ฌด @2chanhaeng@hackers.pub

Lean์€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ์ˆ˜ํ•™์  ์ฆ๋ช…์„ ๊ฒฐํ•ฉํ•œ ๋…์ฐฝ์ ์ธ ์–ธ์–ด๋กœ, ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ˆ˜ํ•™์  ํ‘œํ˜„์‹์œผ๋กœ ์ทจ๊ธ‰ํ•˜์—ฌ ๋ถ€์ž‘์šฉ ์—†๋Š” ๊ณ„์‚ฐ์„ ์ง€ํ–ฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์€ Lean ์ž…๋ฌธ์ž๋ฅผ ์œ„ํ•ด ์—๋””ํ„ฐ ํ†ตํ•ฉ ํ™˜๊ฒฝ์—์„œ์˜ ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ ํ™œ์šฉ๋ฒ•๊ณผ ํ‘œํ˜„์‹ ํ‰๊ฐ€๋ฅผ ์œ„ํ•œ #eval, ํƒ€์ž… ํ™•์ธ์„ ์œ„ํ•œ #check ๋“ฑ ๊ธฐ์ดˆ ๋ช…๋ น์–ด๋ฅผ ์ƒ์„ธํžˆ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. Lean์˜ ํ•ต์‹ฌ์ธ ๊ฐ•๋ ฅํ•œ ํƒ€์ž… ์‹œ์Šคํ…œ์„ ๋ฐ”ํƒ•์œผ๋กœ ์ž์—ฐ์ˆ˜(Nat)์™€ ์ •์ˆ˜(Int)์˜ ์ฐจ์ด๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ, ๊ตฌ์กฐ์ฒด(structure)๋ฅผ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ๊ทธ๋ฃนํ™”์™€ ๊ท€๋‚ฉ์  ์ž๋ฃŒํ˜•(inductive datatype)์„ ํ™œ์šฉํ•œ ํ•ฉ ํƒ€์ž… ๋ฐ ์žฌ๊ท€์  ๊ตฌ์กฐ๋ฅผ ๊นŠ์ด ์žˆ๊ฒŒ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ํŠนํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ถ„ํ•ดํ•˜๋Š” ํŒจํ„ด ๋งค์นญ๊ณผ ๋…ผ๋ฆฌ์  ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ์ข…๋ฃŒ๊ฐ€ ๋ณด์žฅ๋˜์–ด์•ผ ํ•˜๋Š” ๊ตฌ์กฐ์  ์žฌ๊ท€์˜ ์›๋ฆฌ๋ฅผ ๋ช…ํ™•ํžˆ ์„ค๋ช…ํ•˜๋ฉฐ, ํƒ€์ž… ์ธ์ž๋ฅผ ํ†ตํ•œ ๋‹คํ˜•์„ฑ(polymorphism)๊ณผ ์•”์‹œ์  ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ™์€ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์ด ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์„ ์–ด๋–ป๊ฒŒ ๋†’์ด๋Š”์ง€ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋‚˜์•„๊ฐ€ ์ต๋ช… ํ•จ์ˆ˜, ๋„ค์ž„์ŠคํŽ˜์ด์Šค, ๋ฌธ์ž์—ด ๋ณด๊ฐ„๊ณผ ๊ฐ™์€ ํ˜„๋Œ€์  ํŽธ์˜ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด Lean์ด ์ œ๊ณตํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฒฝํ—˜์˜ ์ „๋ฐ˜์„ ์•„์šฐ๋ฆ…๋‹ˆ๋‹ค. ์ด ํฌ์ŠคํŒ…์€ ๋‹จ์ˆœํ•œ ์–ธ์–ด ์Šต๋“์„ ๋„˜์–ด ๋…ผ๋ฆฌ์ ์œผ๋กœ ์™„๊ฒฐ๋œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹œ์Šคํ…œ์˜ ๊ฒฌ๊ณ ํ•จ์„ ์ถ”๊ตฌํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ Lean์˜ ๊ธฐ์ดˆ ํŒจ๋Ÿฌ๋‹ค์ž„์„ ์ดํ•ดํ•˜๋Š” ํ•„์ˆ˜์ ์ธ ์ถœ๋ฐœ์ ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Read more โ†’
1

Me, looking out the window at home: "Wow, I can commute by bike on Thursday when I go in to the office."
Me, looking at Toronto's weather forecast for Wednesday: "Well, shit."

The forecast currently calls for freezing rain with ice buildup (and thus potential power failures) and 5 cm of snow. I guess I should charge up batteries or something.

0
0

ไบบไบบ็”Ÿ่€Œ่‡ช็”ฑ๏ผŒๅ–บๅฐŠๅšดๅŒๅŸ‹ๆฌŠๅˆฉไธŠไธ€ๅพ‹ๅนณ็ญ‰ใ€‚
ไฝขๅ“‹ๆœ‰็†ๆ€งๅŒๅŸ‹่‰ฏๅฟƒ๏ผŒ่€Œไธ”ๆ‡‰็•ถไปฅๅ…„ๅผŸ้—œไฟ‚ๅ˜…็ฒพ็ฅž็›ธๅฐๅพ…ใ€‚

0

์†Œ๋‹ˆ ๊ทธ๋ฃน์€ AI ์ƒ์„ฑ ๊ณก์— ์‚ฌ์šฉ๋œ ์›๊ณก์„ ์‹๋ณ„ํ•˜๊ณ  ๊ฐ ์•„ํ‹ฐ์ŠคํŠธ์˜ ๊ธฐ์—ฌ๋„๋ฅผ ์ •๋Ÿ‰ํ™”ํ•˜์—ฌ ์ž‘๊ณก๊ฐ€๋“ค์ด ๋ณด์ƒ์„ ์š”๊ตฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ธฐ์ˆ ์„ ๊ฐœ๋ฐœ

Sony Group tech can identify original music in AI-generated songs - Nikkei Asia

https://asia.nikkei.com/business/technology/artificial-intelligence/sony-group-tech-can-identify-original-music-in-ai-generated-songs

0
0

๋‹ฌ๋น›์•ฝ์† v5 ์—…๋ฐ์ดํŠธ 1. ํด๋ž˜์Šค ์ง€์›์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค 2. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค 3. ๋žŒ๋‹ค, ํŠœํ”Œ ์ž๋ฃŒํ˜•์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค 4. ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€๊ฐ€ ๋” ์นœ์ ˆํ•ด์กŒ์Šต๋‹ˆ๋‹ค 5. ์•ฑ๊ฐœ๋ฐœ PoC๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค garden.postica.app/dalbit-yakso...

0
0
0
0
0
0
0
0

โ€œAI can make mistakesโ€ might as well be the slogan of our era. Even boosters admit that you need to spin the vibe code slot machine a few times to get a jackpot.

An employee with that degree of consistency would be fired.

So how do we redirect some of that unlimited grace from machines to humans?

productpicnic.beehiiv.com/p/co

0
7
0
0
0
0
0
1