问题
I am learning monads and doing my first "login" case. The steps are simple:
- User input userName and password;
- From database, get user by userName, and get its password saved in database;
- 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