2016-12-13 35 views
3

結果:像getFile(filename).map(parseJson).map(doOtherThings)...如何在JavaScript中使用IO和Either仿函數實現線性流?

流線性。當我使用Either本身一切都是好的,易於

​​

話,我可以做以下

safeUnsureFunction().map((result)=>{ 
    // result is just result from doSomethingCrazyHere function 
    // everything is linear now - I can map all along 
    return result; 
}) 
.map() 
.map() 
.map() 
.map(); 
// linear flow 

問題是,當我m使用IO如:

function safeReadFile(){ 
    try{ 
    return Right(fs.readFileSync(someFile,'utf-8')); 
    }catch(e){ 
    return Left(error); 
    } 
} 

let pure=IO.from(safeReadFile).map((result)=>{ 
    // result is now Either 
    // so when I want to be linear I must stay here 
    // code from now on is not linear and I must generate here another chain 

    return result.map(IdontWant).map(ToGo).map(ThisWay).map(ToTheRightSideOfTheScreen); 
}) 
.map((result)=>{ 
    return result.map(This).map(Is).map(Wrong).map(Way); 
}) 
.map(IwantToBeLienearAgain) 
.map(AndDoSomeWorkHere) 
.map(ButMapFromIOreturnsIOallOverAgain); 

let unpure=function(){ 
    return pure.run(); 
} 

IO是爲了將純粹的功能分離出來嗎?

所以我想分開unpure文件讀取與任何文件錯誤處理。這可能嗎?

如何在IO單元內使用Eithers時具有線性流動?

函數式編程有沒有任何模式呢?

readFile(filename).map(JSON.parse).map(doSomethingElse)....

+0

可能有一個看看這裏https://github.com/fantasyland/fantasy-land –

回答

1

這個唯一的辦法可能是safeRun方法添加到IO 所以在最後,我們將有Either,我們將優雅地從錯誤中恢復的safeReadFile返回

class safeIO { 
    // ... 

    safeRun(){ 
    try{ 
     return Right(this.run()); 
    }catch(e){ 
     return Left(e); 
    } 
    } 

    //... 
} 

相反Either我們必須使用正常readFile

function readFile(){ 
    return fs.readFileSync(someFile,'utf-8'); 
} 

let pure = safeIO.from(readFile) 
.map((result)=>{ 
    // result is now file content if there was no error at the reading stage 
    // so we can map like in normal IO 
    return result; 
}) 
.map(JSON.parse) 
.map(OtherLogic) 
.map(InLinearFashion); 

let unpure = function(){ 
    return pure.safeRun(); // -> Either Left or Right 
} 

或採取IOtry catch邏輯來unpure函數本身沒有任何modyfing IO

let unpure = function(){ 
    try{ 
    return Right(pure.run()); 
    }catch(e){ 
    return Left(e); 
    } 
} 
unpure(); // -> Either