【问题标题】:higher kinded type in typescript from fp-ts and URI来自 fp-ts 和 URI 的打字稿中的更高种类的类型
【发布时间】:2018-04-14 07:10:08
【问题描述】:

在 fp-ts 中,他们为更高种类的类型提供了这种解决方法:

export interface HKT<URI, A> {
  readonly _URI: URI;
  readonly _A: A;
}

而且可以这样使用:

export interface Foldable<F> {
  readonly URI: F;
  reduce: <A, B>(fa: HKT<F, A>, b: B, f: (b: B, a: A) => B) => B;
}

_URI是什么成员,_A是什么成员?

【问题讨论】:

  • String 是一种接地类型,即它具有值。让我们用* 表示地面类型。 [a] 是参数化类型,因为它需要另一个接地类型a。因此它具有* -&gt; * 的形式并被称为一阶类型。现在一个高阶(或高阶)类型从参数化类型[] 中抽象出来,并具有(* -&gt; *) -&gt; * 的形式。 _URI 代表这个第一类参数化类型(* -&gt; *)_A 代表地面类型*。这意味着Foldable 的实例需要参数化类型(例如[])和地面类型(例如String)才能成为地面类型本身。

标签: typescript functional-programming fp-ts


【解决方案1】:

fp-ts的作者This article written解释得很好,结合TypeScript's union types上的文档。

_A 是我们 HKT 中值的类型:HKT&lt;"Option", string&gt; =&gt; Option&lt;string&gt;。我们稍后会看到映射是如何工作的。

_URI 是 HKT 的标识符,例如 Option.ts。它有 2 个实例,NoneSome,它们都以 "Option" 作为它们的 _URI

Taking a look at the usage of F in Foldable 我们可以看到它在Type 类型中使用,与A 一起使用; Type&lt;F, A&gt;。假设F == "Option" &amp; A == string 所以Type&lt;F, A&gt; == Type&lt;"Option", string&gt;,这与Option&lt;string&gt; 非常相似。目前,我们不能将泛型类型传递给另一个泛型,因为它是泛型参数:&lt;F,A&gt;(fa: F&lt;A&gt;) 将无法编译,这是主要问题。

要实现Type&lt;"Option", string&gt; =&gt; Option&lt;string&gt;,有几个“映射”接口(这在文章中有解释)。我们可以看到为Option here 完成了这项工作:

declare module './HKT' {
  interface URI2HKT<A> {
    Option: Option<A>
  }
}

最左边的Option是字符串键,最右边是实际的Option类型,毕竟这是一个普通的记录界面。让我们快速看一下Type的定义:type Type&lt;URI extends URIS, A&gt; = URI2HKT&lt;A&gt;[URI]

URI2HKIT 是从我们的"Option" 到我们实际的Option 的映射。它允许传递 2 个泛型参数来取回包装在更高种类类型中的值类型,从而解决前面提到的泛型问题。

【讨论】:

  • 您的回答确实有帮助。我不明白的一件事是为什么SomeNone 都有_tag 属性和_URI 属性
  • 他们做不同的工作。 _tag 解释为用于区分联合中的各个类型的标记。 _URI 用于从 /lib/HKT github.com/gcanti/fp-ts/blob/… 扩展 URIS 类型。您会在foldable 中找到URIS 的用法:github.com/gcanti/fp-ts/blob/…
  • 与此更相关的是Type类型; type Type&lt;URI extends URIS, A&gt; = URI2HKT&lt;A&gt;[URI];。如果没有extends URIS,我们将无法使用URI 作为索引类型URI2HKT&lt;A&gt;[URI]URI2HKT&lt;A&gt; = {"Option": Option&lt;A&gt;, ...} 生成:URIS = "选项" | ...;
  • 这有一个额外的好处,就是不允许映射接口与_URI 有不同的键。如果我使用{"Poption": Option} 然后尝试使用Type&lt;"Poption", string&gt;,结果类型将是any 而不是Option,因为"Poption" 不在URIS 中。 (虽然很遗憾它解析为 any 而不是编译错误)。
  • @MaxWillmo 看起来像一个打字稿错误(感谢指出),我想我找到了解决它的方法 github.com/gcanti/fp-ts/pull/529
猜你喜欢
  • 2021-07-02
  • 2021-05-26
  • 2021-10-25
  • 2018-01-18
  • 2018-01-27
  • 2021-05-15
  • 1970-01-01
  • 2022-06-23
  • 1970-01-01
相关资源
最近更新 更多