LanguageExt 주요 타입 참조
LanguageExt 라이브러리의 핵심 타입들을 빠르게 참조할 수 있는 가이드입니다.
Fin - 결과 타입
섹션 제목: “Fin - 결과 타입”기본 사용법
섹션 제목: “기본 사용법”// 성공 생성Fin<int> success = 42;Fin<int> success2 = FinSucc(42);
// 실패 생성Fin<int> failure = Error.New("오류 발생");Fin<int> failure2 = FinFail<int>(Error.New("오류"));
// 결과 확인if (result.IsSucc) { /* 성공 */ }if (result.IsFail) { /* 실패 */ }Match - 패턴 매칭
섹션 제목: “Match - 패턴 매칭”var message = result.Match( Succ: value => $"성공: {value}", Fail: error => $"실패: {error.Message}");Map - 값 변환
섹션 제목: “Map - 값 변환”Fin<int> number = 10;Fin<string> text = number.Map(n => n.ToString());// 결과: "10"Bind - 체이닝
섹션 제목: “Bind - 체이닝”Fin<int> Parse(string s) => int.TryParse(s, out var n) ? n : Error.New("파싱 실패");
Fin<int> result = Fin<string>.Succ("42") .Bind(Parse) .Map(n => n * 2);// 결과: 84IfFail - 기본값
섹션 제목: “IfFail - 기본값”int value = result.IfFail(0);int value2 = result.IfFail(error => -1);Validation<Error, T> - 검증 타입
섹션 제목: “Validation<Error, T> - 검증 타입”기본 사용법
섹션 제목: “기본 사용법”// 성공 생성Validation<Error, string> valid = Success<Error, string>("값");
// 실패 생성Validation<Error, string> invalid = Fail<Error, string>(Error.New("오류"));Apply - 병렬 검증
섹션 제목: “Apply - 병렬 검증”var result = ( ValidateName(name), ValidateAge(age), ValidateEmail(email)).Apply((n, a, e) => new User(n, a, e));
// 모든 검증 오류가 수집됨단일 필드 검증
섹션 제목: “단일 필드 검증”Validation<Error, string> ValidateName(string name) => string.IsNullOrEmpty(name) ? Fail<Error, string>(Error.New("이름은 필수입니다")) : Success<Error, string>(name);오류 수집
섹션 제목: “오류 수집”result.Match( Succ: value => Console.WriteLine($"성공: {value}"), Fail: errors => { foreach (var error in errors) Console.WriteLine($"오류: {error.Message}"); });Option - 선택적 값
섹션 제목: “Option - 선택적 값”기본 사용법
섹션 제목: “기본 사용법”// 값이 있는 경우Option<int> some = Some(42);Option<int> some2 = 42; // 암시적 변환
// 값이 없는 경우Option<int> none = None;Match
섹션 제목: “Match”string message = option.Match( Some: value => $"값: {value}", None: () => "값 없음");Map과 Bind
섹션 제목: “Map과 Bind”Option<int> result = Some(10) .Map(n => n * 2) .Bind(n => n > 0 ? Some(n) : None);기본값
섹션 제목: “기본값”int value = option.IfNone(0);int value2 = option.IfNone(() => GetDefaultValue());Either<L, R> - 이진 선택
섹션 제목: “Either<L, R> - 이진 선택”기본 사용법
섹션 제목: “기본 사용법”// Right (성공 값)Either<string, int> right = Right<string, int>(42);
// Left (오류 값)Either<string, int> left = Left<string, int>("오류");Match
섹션 제목: “Match”string result = either.Match( Right: value => $"성공: {value}", Left: error => $"실패: {error}");Error 타입
섹션 제목: “Error 타입”// 기본 오류var error = Error.New("오류 메시지");
// 코드와 메시지var error2 = Error.New("ERR001", "오류 메시지");
// 예외로부터var error3 = Error.New(exception);
// 내부 오류 포함var error4 = Error.New("외부 오류", Error.New("내부 오류"));string code = error.Code;string message = error.Message;Option<Error> inner = error.Inner;Option<Exception> exception = error.Exception;Unit 타입
섹션 제목: “Unit 타입”사용 목적
섹션 제목: “사용 목적”// 반환값이 없는 함수의 결과 타입Fin<Unit> SaveToDatabase(Data data){ // 저장 로직 return unit; // 성공}
// 검증 함수Fin<Unit> ValidateNotEmpty(string value) => string.IsNullOrEmpty(value) ? Error.New("값이 비어있습니다") : unit;Prelude 정적 메서드
섹션 제목: “Prelude 정적 메서드”필수 import
섹션 제목: “필수 import”using static LanguageExt.Prelude;자주 사용하는 메서드
섹션 제목: “자주 사용하는 메서드”// Option 생성Some(42)None
// Either 생성Right<L, R>(value)Left<L, R>(value)
// Validation 생성Success<Error, T>(value)Fail<Error, T>(error)
// Fin 생성FinSucc<T>(value)FinFail<T>(error)
// Unit 값unitLINQ 확장
섹션 제목: “LINQ 확장”SelectMany (Bind)
섹션 제목: “SelectMany (Bind)”var result = from x in Fin<int>.Succ(10) from y in Fin<int>.Succ(20) select x + y;// 결과: 30Select (Map)
섹션 제목: “Select (Map)”var result = from x in Some(10) select x * 2;// 결과: Some(20)Where (Filter)
섹션 제목: “Where (Filter)”var result = from x in Some(10) where x > 5 select x;// 결과: Some(10)컬렉션 확장
섹션 제목: “컬렉션 확장”Seq
섹션 제목: “Seq”// 불변 시퀀스var seq = Seq(1, 2, 3, 4, 5);var head = seq.Head; // Some(1)var tail = seq.Tail; // Seq(2, 3, 4, 5)Arr
섹션 제목: “Arr”// 불변 배열var arr = Array(1, 2, 3);var added = arr.Add(4); // 새 배열 반환Map<K, V>
섹션 제목: “Map<K, V>”// 불변 딕셔너리var map = Map(("a", 1), ("b", 2));var value = map.Find("a"); // Some(1)var updated = map.Add("c", 3);자주 사용하는 패턴
섹션 제목: “자주 사용하는 패턴”체이닝 패턴
섹션 제목: “체이닝 패턴”var result = GetUser(id) .Bind(ValidateUser) .Bind(UpdateUser) .Map(ToResponse);병렬 검증 패턴
섹션 제목: “병렬 검증 패턴”방법 1: 튜플 기반 Apply (권장)
var result = ( ValidateField1(input.Field1), ValidateField2(input.Field2), ValidateField3(input.Field3)).Apply((f1, f2, f3) => new Output(f1, f2, f3));방법 2: fun 기반 개별 Apply
fun 함수는 람다의 타입 추론을 돕는 헬퍼로, Currying을 통해 단계적으로 Apply를 적용합니다.
// fun으로 생성자/팩토리를 감싸고 개별 Apply 호출var result = fun((string f1, string f2, string f3) => new Output(f1, f2, f3)) .Map(f => Success<Error, Func<string, string, string, Output>>(f)) .Apply(ValidateField1(input.Field1)) .Apply(ValidateField2(input.Field2)) .Apply(ValidateField3(input.Field3));또는 Pure를 사용하여 더 간결하게:
var result = Pure<Validation<Error>, Output>( fun((string f1, string f2, string f3) => new Output(f1, f2, f3))) .Apply(ValidateField1(input.Field1)) .Apply(ValidateField2(input.Field2)) .Apply(ValidateField3(input.Field3));두 가지 Apply 방식의 차이를 비교합니다.
| 방법 | 특징 | 사용 시기 |
|---|---|---|
| 튜플 Apply | 간결하고 직관적 | 대부분의 경우 권장 |
| fun 개별 Apply | Currying 기반, 단계적 적용 | 동적 파라미터 개수, 고급 합성 |
옵션 체이닝
섹션 제목: “옵션 체이닝”var result = user .Map(u => u.Address) .Bind(a => a.City) .Map(c => c.Name) .IfNone("Unknown");Functorium 검증 헬퍼
섹션 제목: “Functorium 검증 헬퍼”ValidationRules - 타입 안전 검증 시작점
섹션 제목: “ValidationRules - 타입 안전 검증 시작점”ValidationRules<T>는 값 객체 타입 파라미터를 한 번만 지정하여 검증 체인을 시작하는 정적 클래스입니다. 에러 코드에 값 객체 타입 이름이 자동으로 포함됩니다.
using Functorium.Domains.ValueObjects.Validations.Typed;
// 체이닝 검증: NotNull → ThenNotEmpty → ThenMaxLengthValidationRules<Email>.NotNull(value) .ThenNotEmpty() .ThenMaxLength(255);
// 시작 메서드: NotNull, NotEmpty, MinLength, MaxLength, ExactLength 등// 체이닝 메서드: ThenNotEmpty, ThenMinLength, ThenMaxLength, ThenExactLength, ThenNormalize 등TypedValidation<TValueObject, T> - 타입 정보 전달 래퍼
섹션 제목: “TypedValidation<TValueObject, T> - 타입 정보 전달 래퍼”ValidationRules<T>의 반환 타입으로, 체이닝 중 값 객체 타입 정보를 전달합니다. Validation<Error, T>로 암시적 변환됩니다.
// TypedValidation은 Validation<Error, T>로 암시적 변환TypedValidation<Email, string> typed = ValidationRules<Email>.NotNull(value);Validation<Error, string> validation = typed; // 암시적 변환
// CreateFromValidation에 직접 전달 가능public static Fin<Email> Create(string? value) => CreateFromValidation( ValidationRules<Email>.NotNull(value) .ThenNotEmpty() .ThenMaxLength(255), v => new Email(v));ValidationApplyExtensions - 튜플 Apply 확장
섹션 제목: “ValidationApplyExtensions - 튜플 Apply 확장”ValidationApplyExtensions는 Validation<Error, T> 튜플에 대한 Apply 오버로드를 제공하여, LanguageExt의 제네릭 Apply가 반환하는 K<Validation<Error>, T>를 내부에서 .As()로 변환합니다. 호출 측에서 .As()를 직접 호출할 필요가 없습니다.
using Functorium.Domains.ValueObjects.Validations;
// .As() 없이 concrete Validation<Error, R> 반환var result = ( ValidateAmount(amount), ValidateCurrency(currency)).Apply((a, c) => new Money(a, c));// result 타입: Validation<Error, Money> (K<> 아님)
// 2~5 튜플까지 지원다음 단계
섹션 제목: “다음 단계”프레임워크 타입 선택 가이드를 확인합니다.