【问题标题】:Avoid type variable infered as unknown for manually curried functions避免手动柯里化函数将类型变量推断为未知
【发布时间】:2020-08-18 21:32:47
【问题描述】:

我通常通过箭头语法手动咖喱我的函数。一旦泛型类型参数发挥作用,类型推断似乎就会出现问题:

type Const<A, B> = { const: A };

const Const = <A, B>(x: A): Const<A, B> => ({ const: x });

const map = <F, A, B>(f: (_: A) => B) => (tx: Const<F, B>) => tx;

const inc = (x: number) => x + 1;

const foo = map(inc) (Const("foo")); // Const<unknown, number> instead of <string, number>

Playground

当我取消 map 时,一切都按预期工作。如何在不丢失类型推断的情况下保持函数柯里化?

【问题讨论】:

  • type Const&lt;A, B&gt; = { const: A }; 中的B 类型变量有什么意义?
  • 你当然知道幻象类型。我不是专家,但一个用例是获取值构造函数的正确返回类型,即使此时您没有足够的数据(在给定的示例中,类型构造函数专用于 Const&lt;string, number&gt;)。有时根本没有数据(Nil/List&lt;A&gt;)。我认为Const 只是Either 的变体,没有Right 值构造函数。当然,在一些场景中,它提供了必要的额外多态性。
  • 如果您正在探索其他可编译为 JS 的类型安全语言,我强烈建议您查看 OCaml/ReasonML
  • @Thankyou 嗯,我倾向于坚持使用普通人的语言并充分利用它。但是,Ocaml 似乎是一种可爱的语言。

标签: javascript typescript functional-programming type-inference currying


【解决方案1】:

您只需将类型参数移动到它们实际用作参数的函数中。

在这种情况下Fmap中没有推理站点,它只用于返回类型(从调用的返回类型推断,不是TS做的事情,它在其他场景中确实从返回类型推断但是不是这个)。将类型参数移动到 map 返回的函数,让第二个调用推断 F 并产生预期的类型。

type Const<A, B> = { const: A };

const Const = <A, B>(x: A): Const<A, B> => ({ const: x });

const map = <A, B>(f: (_: A) => B) => <F>(tx: Const<F, B>) => tx;

const inc = (x: number) => x + 1;

const foo = map(inc) (Const("foo")); 

Playground Link

【讨论】:

  • 嗯,那是微不足道的。再次成为新人的感觉很奇怪。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 2020-08-20
  • 2023-03-06
  • 1970-01-01
  • 2013-06-03
  • 2016-01-01
  • 2015-01-26
相关资源
最近更新 更多