2016-08-18 76 views
0

Monad用于优雅地处理错误,但是当Task Task在Nothing之后monads时,它会抱怨fork(它应该由Task提供)不在那里。请参阅下面的代码(使用falktale):如何在处理不同monads时处理错误?

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

原因导致意想不到的结果是因为链(...)实际运行Nothing.map将返回什么没有fork函数。

+0

是的,您需要将'Maybe'转换为'Task'。 – Bergi

+0

是有道理的。但是,如果它不是什么,似乎它总是会返回Nothing,无论是与地图,连锁还是... – Ron

+0

是的,没有一个Functor/Applicative/Monad方法会为类型转换做任何事情。你需要手动做! – Bergi

回答

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