Maybe monad 在 TypeScript 中有何用处?

Gre*_*mas 3 monads typescript option-type

我\xe2\x80\x99m 努力理解 TypeScript 中 Maybe 类型的价值。I\xe2\x80\x99m 试图理解本文中有关在 TypeScript 中实现您自己的 Maybe 类型的代码示例:

\n
enum MaybeType {\n  Just = \'maybe-type__just\',\n  Nothing = \'maybe-type__nothing\',\n}\n\ninterface Just<T> {\n  type: typeof MaybeType.Just\n  value: T\n}\n\ninterface Nothing {\n  type: typeof MaybeType.Nothing\n}\n\ntype Maybe<T>\n  = Just<T>\n  | Nothing\n\nconst Nothing = (): Nothing => ({\n  type: MaybeType.Nothing,\n})\n\nconst Just = <T> (value: T): Just<T> => ({\n  type: MaybeType.Just,\n  value,\n})\n
Run Code Online (Sandbox Code Playgroud)\n

这实际上有什么用?我不明白\xe2\x80\x99 不明白它\xe2\x80\x99s 比一个类型更好T | undefined

\n

我(非常有限)的理解是 Maybe 类型可以使您免受某些运行时错误的影响,并消除整个代码中对 null/未定义检查的需要。但是,\xe2\x80\x99 难道你只是用undefined在代码中散布的支票来交换Nothing在代码中散布的支票吗?

\n

在此示例中,Nothing结果没有value属性,但Just类型有。因此,TypeScript 甚至不会让我访问该值,而无需先确保结果确实是一个Just. 那么\xe2\x80\x99t这是否意味着到处都有大量的检查?为什么不继续做普通的undefined检查呢?I\xe2\x80\x99m 的示例是否只是查看 Maybe 类型的蹩脚实现?

\n

显然我缺少了一些东西,而且还有更多东西。这个东西是如何工作的以及它有什么用处?

\n

mil*_*use 6

您是正确的,您所包含的代码片段在上面提供的有形价值非常少T | undefined

然而,稍后在链接的文章中,作者介绍了其他功能,例如maybeMap就是价值所在:

function maybeMap<A, B> (f: (val: A) => B, m: Maybe<A>): Maybe<B> {
  switch (m.type) {
    case MaybeType.Nothing:
      return Nothing()
    case MaybeType.Just:
      return Just(f(m.value))
  }
}
Run Code Online (Sandbox Code Playgroud)

考虑这种情况:

type Person = {
  name: string;
  age: Maybe<number>; // We don't always know their age
}

const bob:Person = {
  name: "Bobby Tables",
  age: Just(23)
}

Run Code Online (Sandbox Code Playgroud)

现在假设我们有一个寻人系统,其方法如下:

   function findByName(personName: string): Maybe<Person>
Run Code Online (Sandbox Code Playgroud)

这很好地说明了这样一个事实:我们可能找不到合适的人,但我们仍然没有获得太多价值Person | undefined

但现在想象一下我们需要获得我们找到的人的年龄

因为Maybe<T>是一元的,我们可以通过检查来编写一些东西来避免代码乱七八糟undefined

  function findAgeOfPerson(personName: string): Maybe<number> {
    const maybePerson = findByName(personName);
    return maybePerson.map((p) => p.age);
  }
Run Code Online (Sandbox Code Playgroud)

没有if陈述,没有真实性检查。

如果maybePersonNothingmap返回Nothing,但如果不是则(p) => p.age完全安全地执行我们需要的操作。