소개
fp-ts는 TypeScript로 작성된 functional programming 라이브러리입니다. Either는 fp-ts에서 제공하는 데이터 타입 중 하나로, 실패 가능성이 있는 연산을 처리할 때 사용됩니다. Either는 Success 또는 Failure 중 하나의 값을 가집니다.
Either 모나드는 두 개의 값을 가지며, 왼쪽 값을 실패(failure)나 에러(error) 상황, 오른쪽 값을 성공(success) 상황으로 간주합니다. 이를 통해 함수에서 성공과 실패 상황을 구분하여 처리할 수 있습니다.
설명
Either는 실패 가능성이 있는 연산을 처리할 때 사용하는 데이터 타입입니다. Either는 Success 또는 Failure 중 하나의 값을 가집니다. Success는 성공적으로 수행한 결과를 나타내며, Failure는 실패한 원인을 나타냅니다. Either는 fold 메소드를 사용하여 Success와 Failure에 대한 처리를 할 수 있습니다. chain 메소드를 사용하여 실패 가능성이 있는 연산을 체이닝할 수 있으며, map 메소드를 사용하여 Success 값을 매핑할 수 있습니다. getOrElse 메소드를 사용하여 Failure일 경우 기본값을 반환할 수 있습니다.
예를 들어, 데이터베이스에서 데이터를 가져오는 작업을 수행하는 경우, 실패 가능성이 있습니다. 이때, Either를 사용하여 데이터베이스에서 데이터를 가져오는 작업을 처리하면, 데이터베이스에서 데이터를 가져오는 작업이 실패했을 때, 실패 원인을 명확하게 알 수 있습니다. 이는 코드의 가독성을 높여주며, 코드를 더욱 안정적으로 만들어 줍니다.
또한, 외부 API 요청을 처리하는 경우에도 실패 가능성이 있습니다. 이때, Either를 사용하여 외부 API 요청을 처리하면, API 요청이 실패했을 때, 실패 원인을 명확하게 알 수 있습니다. 이는 디버깅을 더욱 쉽게 만들어주며, 코드의 안정성을 높여줍니다.
따라서, Either는 데이터베이스나 캐시, 외부 API 요청 등 실패 가능성이 있는 작업을 처리할 때, 예외 처리보다는 더욱 효과적인 방법입니다.
사용법
Either 생성
Either는 left와 right라는 정적 메소드를 통해 생성할 수 있습니다. left는 실패를 표현하며, right는 성공을 표현합니다.
import { Either, left, right } from 'fp-ts/Either'
type User = {
name: string
age: number
}
function validateUser(user: User): Either<string, User> {
if (user.name === '') {
return left('Name is empty')
} else if (user.age < 18) {
return left('User is too young')
} else {
return right(user)
}
}
JavaScript
복사
코드 설명
Either 사용
생성된 Either는 fold 메소드를 사용하여 Success와 Failure에 대한 처리를 할 수 있습니다.
const result1 = validateUser({ name: '', age: 20 })
result1.fold(
(errorMsg) => console.error(errorMsg),
(user) => console.log(user)
)
// Console output: Name is empty
const result2 = validateUser({ name: 'John', age: 17 })
result2.fold(
(errorMsg) => console.error(errorMsg),
(user) => console.log(user)
)
// Console output: User is too young
const result3 = validateUser({ name: 'Alice', age: 25 })
result3.fold(
(errorMsg) => console.error(errorMsg),
(user) => console.log(user)
)
// Console output: { name: 'Alice', age: 25 }
JavaScript
복사
코드 설명
Either 체이닝
chain 메소드를 사용하여 실패 가능성이 있는 연산을 체이닝할 수 있습니다.
function getUserById(id: string): Either<string, User> {
// ...
}
function validateUserId(id: string): Either<string, string> {
if (id === '') {
return left('ID is empty')
} else {
return right(id)
}
}
function getUserByName(name: string): Either<string, User> {
// ...
}
function validateUserName(name: string): Either<string, string> {
if (name === '') {
return left('Name is empty')
} else {
return right(name)
}
}
function getUserByIdAndName(id: string, name: string): Either<string, User> {
return validateUserId(id).chain((id) =>
validateUserName(name).chain((name) =>
getUserById(id).chain((user) => getUserByName(name))
)
)
}
JavaScript
복사
코드 설명
Either 매핑
map 메소드를 사용하여 Success 값을 매핑할 수 있습니다.
const result4 = validateUser({ name: 'Alice', age: 25 })
const result5 = result4.map((user) => user.age)
console.log(result5)
// Console output: { _tag: 'Right', right: 25 }
JavaScript
복사
Either 변환
getOrElse 메소드를 사용하여 Failure일 경우 기본값을 반환할 수 있습니다.
const result6 = validateUser({ name: '', age: 20 })
const defaultUser = { name: 'Unknown', age: 0 }
const user = result6.getOrElse(() => defaultUser)
console.log(user)
// Console output: { name: 'Unknown', age: 0 }
JavaScript
복사
참고
참고하면 좋은 모듈
•
Option: 실패 가능성이 있는 연산을 처리할 때 사용하는 데이터 타입. Some 또는 None 중 하나의 값을 가집니다.
•
Task: 비동기적인 연산을 처리할 때 사용하는 데이터 타입. Task는 비동기적인 연산을 처리하기 위한 순수 함수를 반환하며, run 메소드를 사용하여 비동기적인 작업을 실행합니다.
•
IO: 부수 효과를 나타내는 연산을 처리할 때 사용하는 데이터 타입. IO는 순수 함수를 반환하며, run 메소드를 사용하여 부수 효과를 실행합니다.
•
Reader: 의존성 주입을 처리할 때 사용하는 데이터 타입. Reader는 의존성을 주입받은 함수를 반환하며, run 메소드를 사용하여 함수를 실행합니다.
•
State: 상태 관리를 처리할 때 사용하는 데이터 타입. State는 현재 상태를 나타내는 값을 가지며, get 메소드를 사용하여 현재 상태를 가져올 수 있습니다. set 메소드를 사용하여 상태를 변경할 수 있으며, modify 메소드를 사용하여 상태를 변경하고 새로운 값을 반환할 수 있습니다.