在Javascript中,这是一个有效的单子转换器吗?
Is this a valid monad transformer in Javascript?
为了更好地理解单子转换器,我实现了一个。由于Javascript是动态类型的,所以我不模仿类型或数据构造函数,而只声明普通的老式Javascript对象,这些对象包含相应的静态函数,以形成特定的monad/transformer。其基本思想是将这些方法应用于容器类型中的一个/多个值。可以说,类型和容器是分开的。
Array
s可以包含任意数量的元素。扩展Array
以实现monad接口是很简单的。Array
s也可以代表maybe
型的两种变体。空的Array
对应nothing
。带有单个元素的Array
对应于just(a)
。因此,我将使用 Array
s作为我的容器类型。请注意,这是一个快速和肮脏的实现,只是为了学习:
const array = {
of: x => Array.of(x),
map: f => ftor => ftor.map(f),
ap: ftor => gtor => array.flatten(array.map(f => array.map(f) (gtor)) (ftor)),
flatten: ftor => ftor.reduce((xs, y) => xs.concat(y), []),
chain: mf => ftor => array.flatten(array.map(mf) (ftor))
}
const maybe = {
of: array.of,
empty: () => [],
throw: ftor => { if (ftor.length > 1) throw Error("indeterministic value"); return ftor },
map: f => ftor => maybe.throw(ftor).map(f),
ap: ftor => gtor => maybe.flatten(maybe.map(f => maybe.map(f) (gtor)) (ftor)),
flatten: array.flatten,
chain: mf => ftor => maybe.flatten(maybe.map(mf) (ftor)),
T: M => {
return {
of: x => M.of(maybe.of(x)),
empty: () => M.of(maybe.empty()),
map: f => ftor => M.map(gtor => maybe.map(f) (gtor)) (ftor),
ap: ftor => gtor => M.flatten(M.map(htor => M.map(itor => maybe.ap(htor) (itor)) (gtor)) (ftor)),
flatten: maybe.flatten,
chain: mf => ftor => M.chain(gtor => maybe.chain(mf) (gtor)) (ftor)
};
}
};
现在我将一个maybe转换器与一元数组结合起来,得到一个可以处理maybe
s的array
s的单子。
const arraym = maybe.T(array);
const add = x => y => x + y;
const addm = x => y => [x + y];
const arrayOfMaybes = [[1],[],[3]]
当我将arraym
视为应用函子时,一切都按预期工作:
// yields: [[11],[],[13]] as expected
arraym.ap(arraym.map(add) (arrayOfMaybes)) (arraym.of(10));
然而,当我应用chain
时,出现了问题:
// yields: [11,13] but [[11],[13]] expected
arraym.chain(x => arraym.chain(y => addm(x) (y)) (arrayOfMaybes)) ([[10]])
是这个问题的原因
- 这不是一个有效的单子转换器?
- 我应用链的方式是错误的?
- 我对结果的期望是错误的?
这个问题的原因是我应用链的方式是错误的?
是的。您需要传递一个返回arraym
的mf
,而不是像addm
那样返回array
。你可以使用
const addmm = x => y => array.map(maybe.of)(addm(x)(y))
arraym.chain(x => arraym.chain( addmm(x) )(arrayOfMaybes))([[10]])
为了帮助解决这个问题,您还可以考虑为每个单子转换器实现lift
。
相关文章:
- Javascript XMLHttpRequest——只有第一个POST请求有效
- 当我的所有 Ng-from 都有效时启用一个按钮
- jQuery"焦点”;在一个实例中有效,但在其他实例中无效
- JSON.parse给了我一个错误,但JSONLint说它'是一个有效的json
- AngularJS分为多个文件-只有最后一个文件有效
- I'我在页面加载时将整个$_SESSION变量放入一个json对象中.虽然这对我有效,但这是一个好的做法吗
- 是什么让新的Date() / 1000成为一个有效的javascript
- JavaScript,数组和函数 - 只有数组的最后一个元素有效
- Javascript——为什么一个document.getElementById()有效,而另一个无效
- 获取字符串中最后一个换行符的最有效方法是什么
- 我如何创建一个Chrome应用程序,有效地充当信息亭模式下的启动页面
- 这是一个有效的JS代码吗
- 多个弹出窗口,但只有一个有效..为什么?
- Jquery - 相同的代码,但只有一个有效
- 使用一堆 setTimeouts 还是一个 setInterval 来刷新一堆对象更有效
- RxJS:如何在传递下一个有效值之前进行一些清理
- 一个Javascript回调模式示例 - 它真的更有效吗?
- 这是一个有效的 XPath 查询吗?
- 我该怎么做才能创建一个永远有效的 HTML 页面
- 所有有效的电子邮件是否至少包含一个@符号