为什么幻想土地规范要求链必须返回同一链的价值?

时间:2016-06-11 13:06:23

标签: javascript types functional-programming monads fantasyland

  

<%= f.select :to_vote, select_list, selected: 'ineligible' %> 方法

     

具有Chain的值必须提供chain方法。连锁,链条   方法有一个参数:

     

chain

     
      
  1. m.chain(f)必须是返回值的函数      
        
    • 如果f不是函数,则f的行为未指定。
    •   
    • chain必须返回相同链的值
    •   
  2.   
  3. f必须返回相同链的值
  4.   

GitHub - fantasyland

给出monad选项的简单实现:

chain

为了保证// prototypes: const someProto = { of(x) { return some(x) }, map(f) { return some(f(this.x)) }, ap(ftor) { return ftor.map(this.x) }, join() { return this.x }, chain(mf) { return this.map(mf).join() } }; const noneProto = { of() { return this }, map() { return this }, ap() { return this }, join() { return this }, chain() { return this } }; // factories: function some(x) { return Object.assign(Object.create(someProto), {x: x}); } function none() { return Object.assign(Object.create(noneProto), {x: null}); } 始终返回选项monad,我必须确保chain(monadic函数)始终返回一个。这是不可能的,因为mf不是实现的一部分。相反,它是在使用monad时定义的:

mf

在第二个方法应用程序中,传递的函数不返回monad,这导致monadic计算的展开结果。我可以通过鸭子打字向// auxiliary function: const sub = y => x => x - y; let a = some(2); let b = some(3); a.chain(x => b.chain(y => some(sub(x)(y)))); // {x: 1} a.chain(x => b.chain(y => sub(x)(y))); // 1 - ouch! chain添加类型检查来解决问题 - 但这会非常难看。

为什么规范要求类型安全? Javascript是动态类型的,我宁愿编写适当的单元测试,而不是在运行时执行类型检查。我会违反规范吗?

1 个答案:

答案 0 :(得分:1)

在第二个示例中,您应该使用 .map()

a.chain(x => b.map(y => sub(x)(y))); 

然后一切都遵循规则。

为了比较,这里是等效的Haskell签名:

fmap  :: m a -> (a ->   b)   -> m b    -- same as .map()
(>>=) :: m a -> (a -> m b)   -> m b    -- same as .chain()

因此,如果您的函数返回monadic值,请使用.chain()。否则使用.map()