首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过多功能的类型记录和具体处理--如何?

过多功能的类型记录和具体处理--如何?
EN

Stack Overflow用户
提问于 2018-11-09 22:40:58
回答 1查看 121关注 0票数 0

我试着在打字稿中写一些免费的咖喱函数。这样做我确实发现了一个问题。

打字本似乎是立即评估类型,并在我的理解,不允许非常好的仓促功能。

让我用一个例子来说明,首先是非咖喱函数。

代码语言:javascript
复制
const fn = (x: number): string => null

function inline <T, U>(fn: (x: T) => U, src: T[]): U[]
function inline <T, U>(fn: (x: T) => U, src: Iterable<T>): Iterable<U>
function inline(fn: (x: any) => any, src: any): any {
  return null
}

const iarr = inline (fn, [1, 2]) // <-- string[]
const iset = inline (fn, new Set([1, 2])) // <-- Iterable<string>

一切就绪,iarriset键入正确。

现在让我们来讨论一下这个函数:

代码语言:javascript
复制
function pointfree <T, U>(fn: (x: T) => U): (src: T[]) => U[]
function pointfree <T, U>(fn: (x: T) => U): (src: Iterable<T>) => Iterable<U>
function pointfree(fn: (x: any) => any) {
  return (src: any): any => null
}

const curried = pointfree (fn) // <-- (src: number[]) => string[]

const parr = curried ([1, 2]) // <-- string[]
const pset = curried (new Set ([1, 2]))
//                    ^^^^^^^^^^^^^^^
// Argument of type 'Set<number>' is not assignable to parameter of
// type 'number[]'.

// or without caching same error
const pset = pointfree (fn) (new Set([1, 2]))

一旦到达pset,就会对pointfree (fn)进行评估,并自动将其转换为第一种重载类型,这是一个数字数组,即使没有缓存为curried

  • 它们是实现我所想要的一种方式吗?
  • 我是不是做错了,或者打字稿需要评估,并且在这种情况下不能延迟评估?(它仍然是静态检查,不需要编译)
  • 他们是处理这种情况的好方法吗?

在fp中,需要部分应用功能是非常普遍的.提前感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-10 00:43:23

当不同的参数类型导致不同的返回类型时,过载非常有用。使用两个具有相同参数类型的不同重载签名是没有用的。那是因为,就像手册上说的:

编译器查看重载列表,然后继续进行第一次重载尝试使用提供的参数调用函数。如果找到匹配项,则选择此重载作为正确的重载。

pointfree的定义中,参数列表对于每个重载都是相同的。这意味着编译器将始终选择第一个,如果它选择一个。

那么,怎样才是正确的方法呢?我建议使用一个返回重载函数的单个调用签名。如下所示:

代码语言:javascript
复制
// call signature, returns overloaded function
function pointfree<T, U>(fn: (x: T) => U): {
  (src: T[]): U[],
  (src: Iterable<T>): Iterable<U>
};
// implementation signature is the same as before 
function pointfree(fn: (x: any) => any) {
  return (src: any): any => null
}

让我们使用它:

代码语言:javascript
复制
const curried = pointfree(fn)
// const curried: {
//  (src: number[]): string[];
//  (src: Iterable<number>): Iterable<string>;
// }

现在您可以看到,curried是一个重载的函数,具有两个调用签名。因此,以下调用的行为与您预期的一样:

代码语言:javascript
复制
const parr = curried([1, 2]) // <-- string[]
const pset = curried(new Set([1, 2])) // <-- Iterable<string>

好吧,希望能帮上忙。祝好运!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53234178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档