FP-TS:管道内的功能被跳过

fp-ts: functions inside pipe are getting skipped

提问人:user1790300 提问时间:10/26/2023 更新时间:10/30/2023 访问量:22

问:

我是函数编程的新手,我遇到了奇怪的行为。我正在为 fp-ts 的管道函数中调用一个包含 tryCatch 函数的函数。似乎包含 tryCatch 的函数从未真正被调用过,即使使用断点,我正在进入下一行,经过包含 tryCatch 的函数,只是不在 tryCatch 函数或链或折叠中。

此外,如果我隔离此函数并像 validateRegistrationForm(user) 一样将其调用到控制台 .log,它似乎打印了一个函数而不是返回值。对于我在网上找到的示例,似乎 tryCatch 返回的是 TaskEither 而不是函数。

我在语法上做错了什么来造成这个问题,我该如何解决它?

下面是管道中从不调用 tryCatch 的函数示例:

const validateRegistrationForm = (user: User): TaskEither<Error, User> => tryCatch(
    async () => {
        const schema = Joi.object().keys({
            userName: Joi.string().min(4).max(255).required(),
            firstName: Joi.string().pattern(new RegExp(/^[a-z\d\-_\s]+$/i)).min(1).max(50).required(),
            lastName: Joi.string().pattern(new RegExp(/^[a-z\d\-_\s]+$/i)).min(1).max(50).required(),
            emailAddress: Joi.string().email().required(),
            password: Joi.alternatives().try(Joi.string(), Joi.number()).required(),
            confirmPassword: Joi.alternatives().try(Joi.string(), Joi.number()).disallow(Joi.ref('password')).required()
        });

        // If post exists, wrap it in a 'some', otherwise return 'none'
        let {error} = await schema.validateAsync(user);

        if (error && error.length > 0)
            throw new ValidationError(error.message);

        return user;
    },
    (reason: any) => reason instanceof Error ? reason : new Error(reason.message)
);

下面是包含管道和链的函数:

const createUser = (user: User): TaskEither<Error, User> => {
    return pipe(
        user,    
        validateRegistrationForm, 
        chain((validContent: User) => {  <-- the breakpoint goes here and stops
            const user: User = {
                confirmPassword: validContent.confirmPassword,
                firstName: validContent.firstName,
                lastName: validContent.lastName,
                emailAddress: validContent.emailAddress,
                password: validContent.password,
                userName: validContent.userName
            };

            return repository.saveUser(user);
        })
    );
};

下面是调用包含管道的函数的代码:

postUser: (req, res) => {
        pipe(
            req.body,
            interactor.createUser,
            fold(<-- this is where the breakpoint jumps to immediately, it calls createUser however
                (error) => async () => {
                    console.error(error);
                    res.status(500).send({ error: 'Failed to retrieve user' });
                },
                (user) => async () => {
                    if (user) {
                        res.status(200).send(user);
                    } else {
                        res.status(404).send({ error: 'User not found' });
                    }
                }
            )
        );
    }
打字稿 FP-TS

评论


答:

0赞 Danielo515 10/30/2023 #1

tryCatch 返回一个新函数,然后您的函数返回该函数。您可以删除包装函数或直接调用它