NonEmptyList · Nel
원소를 최소 하나는 담고 있다고 정적으로 보장되는 리스트 — 누적 API가 에러를 실어 나르는 그릇입니다. 제로 비용입니다: 런타임에 지워지는 확장 타입(extension type)입니다.
강의
"검증 에러의 리스트"에는 어색한 경계 사례가 하나 있습니다.
비어 있는 에러 리스트는 대체 무슨 뜻일까요?
NonEmptyList(별칭 Nel)는 그 질문 자체를 타입
시스템에서 지워 버립니다 — 이 값을 손에 쥐고 있다면 원소가 최소 하나는
있으므로, List.first와 달리 head는 전체
함수(total)이며 예외를 던질 수 없습니다.
에러 누적에 필요한 것이 정확히
이것입니다: EitherNel<E, A> =
Either<Nel<E>, A>, 즉 Left는
언제나 최소 하나의 에러를 실어 나릅니다.
Arrow의 value class NonEmptyList에 대응하는 Dart 쪽
짝입니다. 확장 타입으로 List 위에 얹혀 있어 할당이 전혀
없고 런타임에 지워지며, implements Iterable이므로 모든
fxdart 파이프라인과 for 반복문이 이 값을 그대로 받습니다.
불변식은 컴파일 타임의 규율로 지켜집니다: 생성은 오직
NonEmptyList.of(head, [tail]) 또는
NonEmptyList.orNull(list)(빈 리스트에는 null을
반환합니다 — 비어 있는지 확인하는 일은 경계에서 딱 한 번만 일어납니다)를
통해서만 하세요. list as Nel<int> 같은 캐스트는 그
검사를 우회하며, 책임은 온전히 사용자 몫입니다.
데모 1 · of, orNull, head & tail
데모 2 · map, +, 그리고 파이프라인
데모 3 · toNelOrNull — 어떤 Iterable이든
Nel.orNull은 List를 받기 때문에, 누적
파이프라인은 오류를 패널로 만들기 전에 항상 .toList()
셔플로 끝나야 했습니다. toNelOrNull() 확장(Arrow의
toNonEmptyListOrNull)은 어떤 Iterable이든 —
지연 fx 체인 포함 — 받아 복사한 뒤 Nel?을
바로 돌려줍니다. "오류 없음"은 null, 아니면 비어 있지
않음이 보장된 목록입니다.
직접 해 보기
연습: summarize를 완성해 보세요 — null 경우가
이미 처리되어 있으므로 nel.length와 nel.head는
실패할 수 없습니다.
Nel이 모든 실패를 실어 나르는 곳 ·
Either — toEitherNel()은 실패 하나를 원소 하나짜리 Nel로 끌어올립니다 ·
firstOrNull — 이 타입이 전체 함수로 만들어 주는 nullable 우선 접근자 ·
타입 있는 에러 — 전체 가이드