2016-12-13 12 views
3

Результат: линейный поток, как getFile(filename).map(parseJson).map(doOtherThings)...Как реализовать линейный поток с IO и любыми функторами в функциональном программировании с помощью javascript?

Когда я использую Either сам все красиво и легко

function doSomethingCrazyHere(){ 
    return "something crazy"; 
} 

function safeUnsureFunction(){ 
    try{ 
     return Right(doSomethingCrazyHere()); 
    }catch(e){ 
     return Left(e); 
    } 
} 

, то я просто не могу сделать следующее

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 

проблема, когда я м с использованием ИОО:

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 предназначен для отделения чистых от не очень чистых функций?

Таким образом, я хочу разделить нечеткое чтение файла с помощью любой обработки ошибок файла. Это возможно?

Как иметь линейный поток при использовании Eithers внутри IO monads?

Есть ли какой-либо шаблон в функциональном программировании для этого?

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

+0

может иметь вид здесь https://github.com/fantasyland/fantasy-land –

ответ

1

Единственный путь для этого может быть добавить safeRun метод к IO так что в конце концов мы будем иметь Either и мы грациозно оправиться от ошибки

class safeIO { 
    // ... 

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

    //... 
} 

Вместо safeReadFile, которая возвращает 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 
} 

или взять try catch логики за пределами IO к самым unpure функции без какого-либо модифицирующего IO

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