Monad用于优雅地处理错误,但是当Nothing之后的链任务monad,它将抱怨fork(假设由Task提供)不存在。请参阅下面的代码(使用falktale):
it.only('handle different monads', done => {
const getUserById = id => new Task((reject, result) => setTimeout(
()=>result({ userName: 'ron' })
, 0
))
const getUser = pipe(
Maybe.fromNullable,
chain(getUserById)
)
expect(getUser(null).fork( // complains here: getUser(...).fork is not a function
()=>done(),
x=> done('should not be triggered')
))
})
导致意外结果的原因是因为chain(...)实际运行Nothing.map,如果没有fork函数将返回Nothing。
答案 0 :(得分:0)
通过使用cata / fold解决了这个问题。也因为falktale也许不支持折叠,所以必须使用幻想选项,并且还需要自然变换可能选项。以下是通过的单元测试:
const Maybe = require('data.maybe')
const Either = require('data.either')
const Task = require('data.task')
const {Some, None} = require('fantasy-options')
const {fold} = require('pointfree-fantasy')
const {chain, liftM2} = require('control.monads')
import {pipe, length, curry, prop, equals, tap} from 'ramda'
import {expect} from 'chai'
it.only('handle different monads', done => {
const getUserById = id => new Task((reject, result) => setTimeout(
() => result({ userName: 'ron' })
, 0
))
const maybeToOption = m => m.cata({Just: Some, Nothing: ()=> None})
const getUser = pipe(
Maybe.fromNullable,
maybeToOption,
fold(chain(getUserById), ()=>new Task(rej=>rej()))
)
expect(getUser(null)['fork'](
() => done(),
x => done('should not be triggered')
))
})
同时查看视频:https://youtu.be/oZ6C9h49bu8,它解释了整个事情。