添加包含在 Option Monad 中的两个值

Add Two Values Wrapped inside Option Monad

如果我有两个包含数字的 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))

谢谢:-)

我想到了以下内容。

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)  //?

您在上面的代码片段中遗漏了一些 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)
    )
  )
);

根据context/usage,有多种选择。这里有几个

使用 fp-ts-contrib 中的 Do

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)
);

你应该使用一个序列:

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 进行解释。