std: 마찰 보고의 F1/F3/F6/F7 처리 — 292줄이 244줄로

문법은 건드리지 않았다. 표본이 한 사람이 쓴 300줄 하나뿐인데 되돌리기
비싼 축을 움직일 수는 없다. std 보강만 했다.

추가: List.first/nth, String.join, std/option.cool, std/result.cool.

samples/app 재작성 결과 config.cool 196 → 148줄. head_or, second_or,
Pick, take_at, first_text, first_entry가 통째로 사라졌다. 예측 40줄,
실제 48줄 — F1의 값이 확인됐다.

F3은 줄 수로 값이 안 보인다. main.cool은 96줄 그대로다. 4단 중첩
String.concat이 4줄짜리 String.join 배열이 됐으니 줄 수가 같다. 읽기는
확실히 나아졌다. 줄 수는 읽기 좋음의 대리 지표일 뿐이고 여기서 그 대리가
깨진다 — 다음 개밥 먹기는 다른 것을 재야 한다.

F7: Interp.implemented와 std/*.cool 선언이 서로를 덮는지 테스트가 양방향
으로 검사한다. 어긋나면 빌드가 깨진다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
This commit is contained in:
2026-08-30 16:20:23 +09:00
co-authored by Claude Opus 5
parent 7be05be77f
commit a9f6527825
11 changed files with 260 additions and 90 deletions
+7
View File
@@ -11,6 +11,13 @@ pub fn len[a](xs: List[a]) -> Int
pub fn is_empty[a](xs: List[a]) -> Bool
// 인덱싱 연산자가 언어에 없다. n번째를 꺼내는 일은 이름 있는 함수가 하고,
// 없을 수 있다는 사실은 Option이 말한다 — 범위를 벗어나면 예외도 기본값도
// 아니고 None이다.
pub fn first[a](xs: List[a]) -> Option[a]
pub fn nth[a](xs: List[a], i: Int) -> Option[a]
// 뒤에 하나 붙인 새 리스트. 제자리 수정이 아니다.
pub fn push[a](xs: List[a], x: a) -> List[a]
+15
View File
@@ -0,0 +1,15 @@
// 표준 라이브러리: Option.
//
// 타입 이름이 그 타입에 딸린 함수의 이름공간이다 — Option.map.
pub fn is_some[a](o: Option[a]) -> Bool
pub fn map[a, b, e: effects](
o: Option[a],
f: fn(a) effects e -> b,
) effects e -> Option[b]
pub fn unwrap_or[a](o: Option[a], fallback: a) -> a
// None을 오류로 바꾼다. "없음"과 "왜 없는지"는 다른 정보다.
pub fn ok_or[a, err](o: Option[a], e: err) -> Result[a, err]
+15
View File
@@ -0,0 +1,15 @@
// 표준 라이브러리: Result.
pub fn is_ok[a, err](r: Result[a, err]) -> Bool
pub fn map[a, b, err, e: effects](
r: Result[a, err],
f: fn(a) effects e -> b,
) effects e -> Result[b, err]
pub fn map_err[a, err, err2, e: effects](
r: Result[a, err],
f: fn(err) effects e -> err2,
) effects e -> Result[a, err2]
pub fn unwrap_or[a, err](r: Result[a, err], fallback: a) -> a
+3
View File
@@ -10,6 +10,9 @@ pub fn concat(a: String, b: String) -> String
// 구분자로 자른다. 구분자가 없으면 원본 하나짜리 리스트.
pub fn split(s: String, sep: String) -> List[String]
// split의 반대. concat이 2항이라 여러 조각을 이으면 중첩이 깊어진다.
pub fn join(sep: String, parts: List[String]) -> String
pub fn trim(s: String) -> String
pub fn starts_with(s: String, prefix: String) -> Bool
pub fn contains(s: String, needle: String) -> Bool