上下文
我正在尝试理解monades试图解决的问题,在尝试构建容器和Promise时我有些困惑。
示例
出于练习的目的,我将monad的chain
方法修改为then
,以便可以使用自定义容器编写promises。
const assert = require("assert");
const R = require("ramda");
const makeMonad = value => ({
get: () => value,
map: transform => makeMonad(transform(value)),
then: createMonad => makeMonad(createMonad(value).get())
});
const asyncAdd2 = x => Promise.resolve(x + 2);
const composeP = R.composeWith((f, last) => last.then(f));
const asyncResult = composeP([asyncAdd2, makeMonad])(1);
asyncResult.then(x => assert.equal(x, 3));
console.log("Passed");
在此示例中,由于Promise
API不拥有get
函数而引发错误。实际上,我需要在自定义get
函数中使用此then
函数,以实现可组合性。
因此,在应用程序执行结束时,根据我在composeWith
调用中的参数顺序,我是在promise世界还是在自定义monad世界中。
问题
我现在想知道我在工作并尝试编写monade时是否必须解除所有内容(甚至是诺言?)?
如果我使用10种不同的monade有什么影响?我的意思是,根据订单,我可能会改变我正在努力的世界吗?
这对于创建monades创造者来说很常见吗?我的意思是像创建的makeMonad
一样创建monade定义
感谢您的帮助,我希望我很清楚^^'
答案 0 :(得分:0)
我正在尝试理解monades试图解决的问题
查看此仓库中的示例和参考资料可能会有所帮助 https://github.com/dmitriz/functional-examples
尝试组成一个容器和一个Promise时,我有些困惑。
我想您知道the Promise is not a Monad。
出于该练习的目的,我将monad的chain方法修改为
then
,以便可以使用自定义容器编写promises
作为then
方法breaks Monadic law,
它不适合安全成分。基本上,每次使用函数编写时,都必须仔细检查所有可能的返回值是否为承诺值,并确保始终正确地解开该组合。从根本上来说,这与Monad的观点相违背,Monad使您可以安全地进行撰写而无需花费时间进行详细检查。如果利用Monads是您的目标,则您可能希望从then
切换到chain
。
一个{@ 3}}
- 我现在想知道在工作和尝试编写monade时是否必须取消所有内容(甚至是诺言?)?
您可能希望将所有的Promise包裹在creed
中,然后以通常的方式使用提供的monadic方法。
- 如果我使用10种不同的monade,会有什么影响?我的意思是,根据订单,我可能会改变我正在努力的世界吗?
一元法则适用于固定的monad,即它们仅适用于of
和chain
方法的固定实现。另外chain
期望正确的签名:
chain :: Monad m => m a ~> (a -> m b) -> m b
解密:如果m
是固定的Monad,a
和b
是任何类型,则chain方法要求其参数为a → m b
类型的函数,且m
是同一单子。
换句话说
monad.chain(a => makeMonad(a))
假定函数makeMonad
构成相同的单子。否则,只要使用chain
,就需要将结果包装到正确的monad中。
要使它与诺言一起安全地工作,请始终将其包装到Creed中以确保使用相同的monad,然后仅在构成和依赖于monadic法则时才使用map
和chain
。或使用then
冒着风险,担心细节:)
- 这对于创建monades创造者来说是常见的吗?我的意思是像我编写的makeMonad一样创建monade定义
这仅在您具有实际值开始时才起作用,请参见例如此处:Creed
但是Monad的功能之一就是处理您无法(或不想)直接访问的值,例如IO Monad。在这些情况下,您只能使用提供的运算符来创建或不可以创建Monad。这说明了原生JS Promise的问题-在不更改其值的情况下,您无法以任何方式使它们成为Monad。原生JS承诺会始终尝试解开“ theneable”,因此无法将其存储为值,从而使任何合成通常都不安全。