How to fork and merge monads?

前提是你 提交于 2020-02-28 17:27:23

问题


I am learning monads and doing my first "login" case. The steps are simple:

  1. User input userName and password;
  2. From database, get user by userName, and get its password saved in database;
  3. compare the input password with the one in the database.

From the above, there is a requirements to fork 2 monads and merge them to compare.

I read nearly all javascripts FP books and monads implementations I can think of, but still cannot found any solutions. The below is what I got so far, it works, but it looks complex and not very well readable. I am wondering if there is a standard way to handle this common problem. By they way, I am using falktale and ramda.

const Task = require('data.task')
const {chain, liftM2} = require('control.monads')
import {pipe, length, curry, prop, equals, tap} from 'ramda'

it.only('sign in', done => {
    const merge = curry((p, f, g, x) => liftM2(p, f(x), g(x)))

    const signIn = pipe(
        lift,
        chain(merge(equals,
            pipe(lift, map(prop('password'))),
            pipe(lift, map(prop('userName')), chain(getUserByUserName), map(prop('password')))
        ))
    )

    signIn({ userName: 'ron', password: '123' })fork(
        (err) => { console.log('error happens'); done(err) },
        matched => { expect(matched).to.eql(true); done() }
    )
})

const getUserByUserName = (id) => new Task((reject, result) => setTimeout(
    userName => userName === 'ron'
        ? reject('not found')
        : result({ userName: 'ron', password: '123' })
    , 0
))

来源:https://stackoverflow.com/questions/39022140/how-to-fork-and-merge-monads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!