2017-06-13 39 views
0

我想弄清楚一種方法來在TypeScript中對monadic庫進行優化。雖然monad本身的實現令人愉快,但它的使用看起來像熟悉的回調地獄。TypeScript中的Do notation

我想知道是否有辦法劫持async/await或yield/for..of的現有monadic語法糖,但我必須承認我在連接點時遇到了一些麻煩。是否有可能在既不是Promise也不是Iterable的東西上使用這些構造,並且與由反應組件構成的continuation monad不同?

+1

你可能會添加一些代碼,以準確顯示你的意思,並給我們一些工作? –

+0

我對TypeScript和JavaScript很少了解,但是mayby [this](https://github.com/Risto-Stevcev/do-notation)可以移植到TypeScript中嗎? – phg

回答

1

我有限的時間,但這裏的使用延續單子Cont作爲一個例子

// first: WITHOUT do-notation 
 

 
const Cont = f => ({ 
 
    runCont: f, 
 
    chain: g => 
 
    Cont(k => f (x => g (x) .runCont (k))) 
 
}) 
 

 
Cont.of = x => 
 
    Cont(k => k (x)) 
 

 
const result = Cont.of (2) .chain (x => 
 
    Cont.of (3) .chain (y => 
 
    Cont.of (x + y))) 
 

 
result.runCont (console.log) 
 
// 5

現在一個快速的小例子使用排序的do -notation同樣的事情 - do是JS中的保留關鍵字,所以我將其命名爲我的功能run

// second: WITH do-notation 
 

 
const run = g => { 
 
    const next = x => { 
 
    let {value, done} = g.next (x) 
 
    return done 
 
     ? value 
 
     : value.chain (next) 
 
    } 
 
    return next (null) 
 
} 
 

 
const Cont = f => ({ 
 
    runCont: f, 
 
    chain: g => 
 
    Cont(k => f (x => g (x) .runCont (k))) 
 
}) 
 

 
Cont.of = x => 
 
    Cont(k => k (x)) 
 

 
const result = run (function*() { 
 
    let x = yield Cont.of (2) 
 
    let y = yield Cont.of (3) 
 
    return Cont.of (x + y) 
 
}()) 
 

 
result.runCont (console.log) 
 
// 5


警告:可能使用async/await但隨後你的價值觀堅持承諾的內部獲得 - 這很可能在大多數情況下煩人。

+0

如果你真的想依靠這個,你會想要得到一些錯誤檢查 - 現在它假定生成的類型有一個「鏈」方法。 – naomik

+0

我認爲生成器函數不適用於列表monad。除了它們是有狀態的,你不能在高階函數中產生,因此沒有map/reduce等。但是,我也不知道更好的方法。但我會考慮的。 – ftor