【问题标题】:Add Two Values Wrapped inside Option Monad添加两个包裹在 Option Monad 中的值
【发布时间】:2020-09-12 02:12:33
【问题描述】:

如果我有两个包含数字的 Option monad,如何在不退出 monad 的情况下将它们相加?

import {fromNullable, pipe, chain, map} from 'fp-ts/lib/Option'
let c1 = fromNullable(10)
let c2 = fromNullable(20)

// This is where I'm stuck. I would expect c3 to be an Option<number> containing 30. 
let c3 = pipe(c1, chain(map((x) => x + c2))

谢谢你:-)

【问题讨论】:

    标签: fp-ts


    【解决方案1】:

    你应该使用一个序列:

    const c1 = Option.some(10);
    const c2 = Option.some(20);
    
    assertEquals(Array.sequence(Option.option)([c1, c2]), Option.some([10, 20]));
    

    请查看https://fsharpforfunandprofit.com/posts/elevated-world-4/#sequence 了解详情。

    【讨论】:

    • 嗨。感谢那!不过,这并不是我所追求的。这似乎是将它们组合成一个选项内的数组,我希望在其中添加它们。不过我不知道序列,你用那个很棒的链接把我送进了兔子洞。
    【解决方案2】:

    您在上面的 sn-p 中缺少一些 pipe 间接。这将起作用:

    import { option } from "fp-ts";
    import { pipe } from "fp-ts/function";
    
    declare const c1: option.Option<number>;
    declare const c2: option.Option<number>;
    
    const c3 = pipe(
      c1,
      option.chain(c1 =>
        pipe(
          c2,
          option.map(c2 => c1 + c2)
        )
      )
    );
    

    根据上下文/使用情况,有多种选择。这里有几个

    使用来自fp-ts-contribDo

    import { Do } from "fp-ts-contrib/lib/Do";
    
    const c3b = Do(option.option)
      .bind("c1", c1)
      .bind("c2", c2)
      .return(({ c1, c2 }) => c1 + c2);
    

    使用来自Apply 模块的sequenceS

    import { sequenceS } from "fp-ts/Apply";
    
    const c3c = pipe(
      sequenceS(option.option)({ c1, c2 }),
      option.map(({ c1, c2 }) => c1 + c2)
    );
    

    【讨论】:

    • 谢谢。他们真棒。我刚刚重申的一件事,我没有在问题中指定,是我希望能够处理任何一个为无的变量。我希望整个结果为 none.
    • 是的,如果 c1、c2 中的一个或两个是 None&lt;number&gt;,那么整个计算也会产生 None&lt;number&gt;(我提供的所有示例都是如此)
    • 啊……他们就是这样。我只是再次尝试了它们,它们都很好。当我昨晚尝试时,我一定很累。再次感谢您的详细回答。你给了我很多东西让我咬牙切齿。
    【解决方案3】:

    我想出了以下内容。

    import {pipe} from 'fp-ts/lib/function'
    import { getFoldableComposition } from 'fp-ts/Foldable'
    import { array } from 'fp-ts/Array'
    import { option,fromNullable } from 'fp-ts/Option'
    import { monoidSum } from 'fp-ts/Monoid'
    
    const F = getFoldableComposition(array, option)
    
    let c1 = fromNullable(10) 
    let c2 = fromNullable(20)
    let c3 = fromNullable(undefined)
    let c4 = fromNullable(undefined)
    
    // returns 30
    F.reduce([c1,c2],0, monoidSum.concat)  //?
    // alternatively, also returns 30
    F.reduce([c1,c2],0, (i,j)=>i+j)  //?
    
    // The above unwarp the result though. To return as the monad need to lift the result
    
    // returns some(30)
    pipe(F.reduce([c1,c2],0, (i,j)=>i+j), fromNullable)  //?
    
    // returns some(0)
    pipe(F.reduce([c3,c4],0, (i,j)=>i+j), fromNullable)  //?
    

    【讨论】:

      猜你喜欢
      • 2013-05-03
      • 2015-05-21
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      • 1970-01-01
      • 2020-05-02
      相关资源
      最近更新 更多