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

时间:2021-10-20 22:06:20

Monad is used to handle error gracefully, but when chain Task monads after Nothing, it will complain fork(which supposed provided by Task) is not there. See the code below (using falktale):

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')
    ))
})

The reason cause the unexpected result is because chain(...) actually running Nothing.map which will return Nothing without fork function.

导致意外结果的原因是因为链(...)实际运行Nothing.map,如果没有fork函数将返回Nothing。

1 个解决方案

#1


0  

Solved the problem via using cata/fold. Also because the falktale Maybe doesn't support fold, so have to use fantasy option, and also need to nature transform maybe to option. The below is the passed unit test:

通过使用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')
    ))
})

Also check the video: https://youtu.be/oZ6C9h49bu8, it explained the whole thing deeply.

另请查看视频:https://youtu.be/oZ6C9h49bu8,它深入解释了整个事情。

#1


0  

Solved the problem via using cata/fold. Also because the falktale Maybe doesn't support fold, so have to use fantasy option, and also need to nature transform maybe to option. The below is the passed unit test:

通过使用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')
    ))
})

Also check the video: https://youtu.be/oZ6C9h49bu8, it explained the whole thing deeply.

另请查看视频:https://youtu.be/oZ6C9h49bu8,它深入解释了整个事情。