Javascript 处理对象时如何组合/管道函数?

Javascript 处理对象时如何组合/管道函数?,javascript,functional-programming,Javascript,Functional Programming,假设我有一个请求对象: { 用户:{/*用户数据:用户名、电子邮件等。*/} 发布:{/*发布数据:内容、日期等。*/} } 请求对象的示例: { 用户:{ id:'123' 用户名:“kibe” 电邮:'blabla@gmail.com' } 职位:{ 内容:“我的新帖子!” 日期:20/02/2004 } } 现在,我有两个函数:validateUser和validatePost。它们都返回一个Maybemonad,因为它们可能会失败 那我怎么能这样做呢 函数保存后(请求){ 退货申请

假设我有一个
请求
对象:

{
用户:{/*用户数据:用户名、电子邮件等。*/}
发布:{/*发布数据:内容、日期等。*/}
}
请求
对象的示例:

{
用户:{
id:'123'
用户名:“kibe”
电邮:'blabla@gmail.com'
}
职位:{
内容:“我的新帖子!”
日期:20/02/2004
}
}
现在,我有两个函数:
validateUser
validatePost
。它们都返回一个
Maybe
monad,因为它们可能会失败

那我怎么能这样做呢

函数保存后(请求){
退货申请
|>validateUser//如果validateUser返回Success(用户)或Failure(错误),我将如何传递帖子?
|>验证邮件
|>savePostToDb
|>嗯
}
我是否应该创建一个由
validateUser
validatePost
组成的函数
validateRequest
?但是,我如何只将
post
对象赋予
savePostToDb
?如果
savePostToDb
也需要用户ID怎么办

函数保存后(请求){
退货申请
|>validateRequest//返回一个或多个单子
|>savePostToDb//只需要用户ID和帖子,如何传递这些信息?
|>嗯
}
希望这些问题有意义。我是FP新手,虽然我了解它的范例,但我没有设计一个简单的程序


谢谢

是的,您应该创建
validateRequest
savePostToDb
方法,这些方法将返回布尔值。然后你可以用这两种新方法简单地创建两个函数,并将它们组合在一起。请看我的示例,我将如何简单地做到这一点:

// Here some simple Left/Right to Just and Nothing (Maybe)-Monade function to work with
const Left    = x => f => _ => f(x);
const Right   = x => _ => g => g(x);

const Nothing = Left();
const Just    = Right;

// your maybe-validateRequest function
const maybeValidateRequest  = request =>
    validateRequest(request)
        ? Just(user)
        : Nothing

// your maybe-postToDb function
const maybePostToDb = request =>
    savePostToDb(request)
        ? Just(request)
        : Nothing

// and finally compose those two maybes and do the postRequest finally
const savePost = request =>
    maybeValidateRequest(request)
    (() => console.error("Validation failed"))
    (_  =>
        maybePostToDb(request)
        (() => console.error("Save to DB failed")))
        (_  => postRequest(request))    // when it's everything passed,the postRequest can be safely made

道具

我们编写了一个简单的
prop
函数,可以安全地查找对象的属性。如果它们存在,我们会得到一个
只是
包装的值,否则我们会得到
-

const fromNullable=x=>
x==null
? 没有什么
:刚好(x)
常数prop=k=>t=>
fromNullable(t[k])
道具

不过,您有嵌套的属性,所以让我们使用任意序列的
道具
-

constprops=(k,…ks)=>t=>
ks长度
? 道具(k)(t)绑定(道具(…ks))
:支柱(k)(t)
验证

现在我们可以编写一个简单的
validate
corroutine-

函数*validate(t)
{const id=yield props(“用户”、“id”)(t)
const username=收益道具(“用户”、“用户名”)(t)
const email=收益道具(“用户”、“电子邮件”)(t)
const post=收益道具(“post”、“content”)(t)
施工日期=收益率道具(“后”、“日期”)(t)
只返回({id,用户名,电子邮件,帖子,日期})//f(v)})
演示

展开下面的代码段,在您自己的浏览器中验证结果-

const Nothing=
({bind:=>Nothing})
常数Just=v=>
({bind:f=>f(v)})
常量fromNullable=x=>
x==null
? 没有什么
:刚好(x)
常数prop=k=>t=>
fromNullable(t[k])
常量属性=(k,…ks)=>t=>
ks长度
? 道具(k)(t)绑定(道具(…ks))
:支柱(k)(t)
函数协程(f)
{函数next(v)
{let{done,value}=f.next(v)
返回完成?值:value.bind(下一步)
}
返回下一个()
}
函数*验证(t)
{const id=yield props(“用户”、“id”)(t)
const username=收益道具(“用户”、“用户名”)(t)
const email=收益道具(“用户”、“电子邮件”)(t)
const post=收益道具(“post”、“content”)(t)
施工日期=收益率道具(“后”、“日期”)(t)
仅返回({id,用户名,电子邮件,帖子,日期})
}
康斯特医生=
{用户:{id:'123',用户名:'kibe',电子邮件:'blabla@gmail.com},帖子:{content:'mynewpost!',日期:'20/02/2004'}

coroutine(validate(doc)).bind(console.log)
我可能会做一些类似于
请求|>和(validateRequest,validatePost)|>保存
…@jonaswillms嘿,非常感谢。很抱歉,你介意解释一下
的功能吗?尝试了搜索,但没有效果:/可能类似于
const和=(…checks)=>value=>checks.every(it=>it(value))?{value}:{}