使用 fp-ts 与非功能性代码的互操作性

2025-05-24

使用 fp-ts 与非功能性代码的互操作性

有时您被迫与非以函数式风格编写的代码进行互操作,让我们看看如何处理它。

哨兵

用例:可能失败并返回陪域特殊值的 API。

例子:Array.prototype.findIndex

解决方案:Option

import { Option, none, some } from 'fp-ts/Option'

function findIndex<A>(
  as: Array<A>,
  predicate: (a: A) => boolean
): Option<number> {
  const index = as.findIndex(predicate)
  return index === -1 ? none : some(index)
}
Enter fullscreen mode Exit fullscreen mode

undefinednull

undefined用例:可能失败并返回(或null)的API 。

例子:Array.prototype.find

解决方案:OptionfromNullable

import { Option, fromNullable } from 'fp-ts/Option'

function find<A>(as: Array<A>, predicate: (a: A) => boolean): Option<A> {
  return fromNullable(as.find(predicate))
}
Enter fullscreen mode Exit fullscreen mode

例外

用例:可能抛出的 API。

例子:JSON.parse

解决方案:EithertryCatch

import { Either, tryCatch } from 'fp-ts/Either'

function parse(s: string): Either<Error, unknown> {
  return tryCatch(
    () => JSON.parse(s),
    (reason) => new Error(String(reason))
  )
}
Enter fullscreen mode Exit fullscreen mode

随机值

用例:返回非确定性值的 API。

例子:Math.random

解决方案:IO

import { IO } from 'fp-ts/IO'

const random: IO<number> = () => Math.random()
Enter fullscreen mode Exit fullscreen mode

同步副作用

用例:读取和/或写入全局状态的 API。

例子:localStorage.getItem

解决方案:IO

import { Option, fromNullable } from 'fp-ts/Option'
import { IO } from 'fp-ts/IO'

function getItem(key: string): IO<Option<string>> {
  return () => fromNullable(localStorage.getItem(key))
}
Enter fullscreen mode Exit fullscreen mode

用例:读取和/或写入全局状态并可能抛出的 API。

例子:readFileSync

解决方案:IOEithertryCatch

import * as fs from 'fs'
import { IOEither, tryCatch } from 'fp-ts/IOEither'

function readFileSync(path: string): IOEither<Error, string> {
  return tryCatch(
    () => fs.readFileSync(path, 'utf8'),
    (reason) => new Error(String(reason))
  )
}
Enter fullscreen mode Exit fullscreen mode

异步副作用

用例:执行异步计算的 API。

示例:从标准输入读取

解决方案:Task

import { createInterface } from 'readline'
import { Task } from 'fp-ts/Task'

const read: Task<string> = () =>
  new Promise<string>((resolve) => {
    const rl = createInterface({
      input: process.stdin,
      output: process.stdout
    })
    rl.question('', (answer) => {
      rl.close()
      resolve(answer)
    })
  })
Enter fullscreen mode Exit fullscreen mode

用例:执行异步计算并可能拒绝的 API。

例子:fetch

解决方案:TaskEithertryCatch

import { TaskEither, tryCatch } from 'fp-ts/TaskEither'

function get(url: string): TaskEither<Error, string> {
  return tryCatch(
    () => fetch(url).then((res) => res.text()),
    (reason) => new Error(String(reason))
  )
}
Enter fullscreen mode Exit fullscreen mode
文章来源:https://dev.to/gcanti/interoperability-with-non-functions-code-using-fp-ts-432e
PREV
我在 2020-2021 年发现的 165+ 开发者资源 资源列表 HTML 资源 CSS 资源 JavaScript 资源 React 资源 WordPress 资源 Git 和 CLI 资源 托管资源 优化资源 数据库资源 其他 Web 开发资源 职业资源 设计资源
NEXT
Netflix 系统设计-后端架构