【发布时间】:2022-06-13 17:23:34
【问题描述】:
我刚开始使用 fp-ts lib 学习函数式编程世界。目前我可以理解这个库提出的函数的基本概念,但我不明白如何将它们全部粘合到单个数据流中。
我想分享一个我想要实现的用户故事,并将其用作此问题的示例。听起来是这样的:
- 用户应该可以预约选定的专家
我知道此时这对您没有意义,但让我向您展示在同一页面上的代码看起来如何。
注意:这是伪代码,使其更具可读性
const inputData = {
userId: 1,
specialistId: 2,
selectedServicesIds: ['a', 'b', 'c'],
startTime: 'today at 12:00'
}
const user = await fetchUserById(inputData.userId)
if (user === null) {
throw 'User not found'
}
const specialist = await fetchSpecialistById(inputData.specialistId)
if (user === null) {
throw 'Specialist not found'
}
const workingDay = await fetchWorkingDay(inputData.specialistId, inputData.startTime)
if (workingDay === null) {
throw 'WorkingDay not found'
}
const selectedServices = await fetchSelectedServices(inputData.specialistId, inputData.selectedServicesIds)
if (selectedServices.length < inputData.selectedServices) {
throw 'Some selected services are not belong to the selected specialist'
}
const selectedServicesDuration = calculateDuration(selectedServices)
const appointmentEndTime = addMinutes(inputData.startTime, selectedServicesDuration)
const existingAppointments = await fetchAppointmentsOfSpeciallist(inputData.specialistId)
const isAppointmentOverlapExistingAppointments = isOverlaps(existingAppointments, inputData.startTime, appointmentEndTime)
if (isAppointmentOverlapExistingAppointments) {
throw 'Appointment overlap existing appointments'
}
return new Appointment(inputData.userId, inputData.specialistId, ...)
如您所见,这是典型的命令式代码:
- 获取输入数据
- 从数据库中获取数据
- 应用验证
- 返回结果
现在我使用 fp-ts 和 Do-notation 能够实现的目标
pipe(
RTE.Do,
RTE.apS('user', fetchUserById(args.input.clientId)),
RTE.apSW('specialist', fetchSpecialistById(args.input.specialistId)),
RTE.apSW('workingDay', fetchWorkingDay(args.input.specialistId, args.input.startDateTime)),
RTE.apSW('assignedServices', getAssignedServicesOfSpecialist(args.input.specialistId, args.input.servicesIds))
RTE.map({ user, specialist, workingDay, assignedServices } => {
// Do I need to write all logic here?
})
如您所见,获取相关数据的并行请求很少,但不知道下一步该做什么。如果我只是将前面示例中的命令式逻辑放在 RTE.map 函数中,它看起来就像我用一些 fp-ts 函数包装了命令式代码。
您能否给我一个建议,告诉我如何将其拆分为不同的功能以及如何将它们粘合在一起?
【问题讨论】:
标签: fp-ts