处理不同的monad时如何处理错误?

时间:2016-08-18 14:59:20

标签: javascript functional-programming

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。

1 个答案:

答案 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,它解释了整个事情。