标签: fp-ts

使用 fp-ts 重写一个用记录器包装的小函数

我想尝试使用 fp-ts 重写代码的某些部分,并考虑重构以下方法:

export const createApiServer = () => {
    logger.info("Starting World Server API");

    const apiServer = express()
        // 3rd party middleware
        .use(helmet())
        .use(bodyParser.json())
        .use(cors())
        // Root route
        .get("/", (_, result) => result.sendStatus(httpStatusCodes.OK))
        // 404 - Not Found
        .use((_, result) => result.sendStatus(httpStatusCodes.NOT_FOUND))
        // 500 - Internal Server Error
        .use(errorLoggerMiddleware)
        .use(errorResponseMiddleware);

    logger.verbose(`Initialized World Server API in ${process.uptime().toFixed(3)} seconds`);

    return apiServer;
};
Run Code Online (Sandbox Code Playgroud)

在阅读了IO副作用类型后,我尝试按如下方式使用它:

const info = (message: string) => new IO(() => log.info(message));
const verbose = (message: string) => new …
Run Code Online (Sandbox Code Playgroud)

typescript fp-ts

2
推荐指数
1
解决办法
1550
查看次数

打字稿区分联合的 switch 语句的替代方法

我创建了这个游乐场,这里是代码:

type BundlerError = Error;
type BundlerWarning = Error;

export type BundlerState =
  | { type: 'UNBUNDLED' }
  | { type: 'BUILDING'; warnings: BundlerWarning[] }
  | { type: 'GREEN'; path: string;  warnings: BundlerWarning[] }
  | { type: 'ERRORED'; error: BundlerError }

const logEvent = (event: BundlerState) => {
    switch (event.type) {
      case 'UNBUNDLED': {
        console.log('received bundler start');
        break;
      }
      case 'BUILDING':
        console.log('build started');
        break;
      case 'GREEN':
        if(event.warnings.length > 0) {
          console.log('received the following bundler warning');

          for (let warning …
Run Code Online (Sandbox Code Playgroud)

typescript fp-ts

2
推荐指数
1
解决办法
847
查看次数

如何使用Task monad?(fp-ts)

import * as T from 'fp-ts/lib/Task'
import { pipe, flow } from 'fp-ts/lib/function'

const getHello: T.Task<string> = () => new Promise((resolve) => {
  resolve('hello')
})
Run Code Online (Sandbox Code Playgroud)

我理解它的目的Task以及为什么它很重要。问题是我真的不知道如何正确使用它或用它进行创作。

如果我只是打电话getHello(),它会给我Promise<pending>

console.log(getHello()) // returns Promise<pending>
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做:

const run = async () => {
  const hello = await getHello()
  console.log(hello) // prints 'hello'
}
Run Code Online (Sandbox Code Playgroud)

有用。

但是这个:

const waitAndGet = async () => {
  return await getHello()
}

console.log(waitAndGet()) // prints Promise<pending>
Run Code Online (Sandbox Code Playgroud)

没有。

而且,我怎样才能用它来作曲呢?就像这样:

const waitAndGet = async () => …
Run Code Online (Sandbox Code Playgroud)

functional-programming typescript fp-ts

2
推荐指数
1
解决办法
4193
查看次数

使用 IO-TS 将 JS 字符串数组转换为联合

我正在使用io-ts,我想知道是否有办法将字符串数组(文字)转换为此类文字的并集。例如:

export const CONTROLS = [
  "section",
  "text",
  "richtext",
  "number",
];

export const ControlType = t.union(
  // What to do here? Is this even possible? This is what came to mind but it's obviously wrong.
  // CONTROL_TYPES.map((type: string) => t.literal(type))
);

Run Code Online (Sandbox Code Playgroud)

我不知道这是否可行,但鉴于这io-ts只是 JS 函数,我不明白为什么不可以。我只是不知道如何。

这种情况下的最终结果应该是(使用 io-ts):

export const ControlType = t.union(
  t.literal("section"),
  t.literal("text"),
  t.literal("richtext"),
  t.literal("number"),
);
Run Code Online (Sandbox Code Playgroud)

javascript typescript fp-ts

2
推荐指数
1
解决办法
371
查看次数

将 IO 映射到 fp-ts 中的任一数组

谁能帮我弄清楚如何做到这一点fp-ts

const $ = cheerio.load('some text');
const tests = $('table tr').get()
  .map(row => $(row).find('a'))
  .map(link => link.attr('data-test') ? link.attr('data-test') : null)
  .filter(v => v != null);
Run Code Online (Sandbox Code Playgroud)

我可以用它来做这一切,TaskEither但我不知道如何将它与 混合IO,或者我根本不应该使用它IO

这是我到目前为止想出的:

const selectr = (a: CheerioStatic): CheerioSelector => (s: any, c?: any, r?: any) => a(s, c, r);

const getElementText = (text: string) => {
  return pipe(
    IO.of(cheerio.load),
    IO.ap(IO.of(text)),
    IO.map(selectr),
    IO.map(x => x('table tr')),
    // ?? don't know what to do here
  );
} …
Run Code Online (Sandbox Code Playgroud)

typescript fp-ts

1
推荐指数
1
解决办法
1627
查看次数

如何处理 fp-ts 中的“else if”

很多时候我注意到我正在努力如何实现一个带有多个 if-else 条件的非常简单的流程图。

流程图

这个示例看起来太冗长,并且如果稍后添加更多条件,则无法真正扩展:

import * as O from "fp-ts/lib/Option"

type Category = {
  id: string
  slug: string
}

const getCategory = (category: unknown, categories: Category[]) =>
  pipe(
    O.fromNullable(category),
    O.filter((c): c is Partial<Category> => typeof c === 'object'),
    O.chain((category): O.Option<Category> => {
      if (category?.id) {
        return O.fromNullable(categories.find((item) => item.id === category.id))
      }

      if (category?.slug) {
        return O.fromNullable(categories.find((item) => item.slug === category.slug))
      }

      return O.none
    }
  )
)
Run Code Online (Sandbox Code Playgroud)

如果您将类别列表替换为对数据库的调用,并且还希望捕获 Either.left 中可能出现的错误,那么情况会变得更加复杂。

带错误捕获的流程图

所以我的问题是:我们应该如何处理 fp-ts 中的一个或多个“else if”语句?

typescript fp-ts

1
推荐指数
2
解决办法
3988
查看次数

带有选项和链的 fp-ts 管道不起作用

我有这个示例代码:

import {none, some, chain} from 'fp-ts/lib/Option';
import {pipe} from 'fp-ts/lib/pipeable';

const f1 = (input: string) => {
    return some(input + " f1")
};
const f2 = (input: string) => {
    return some(input + "f2")
};
const f3 = (input: string) => {
    return none;
};
const f4 = (input: string) => {
    return some(input + "f4");
};

const result = pipe(
    f1,
    chain(f2),
    chain(f3),
    chain(f4),
)("X");

console.log("result", result);
Run Code Online (Sandbox Code Playgroud)

我收到这个编译时错误

Argument of type '(input: string) => Option<string>' is not assignable …
Run Code Online (Sandbox Code Playgroud)

functional-programming typescript fp-ts

0
推荐指数
1
解决办法
1028
查看次数