如何声明必须 return 其参数之一的函数的签名? (任何语言*)

How do I declare the signature of a function that must return one of its arguments? (in any language*)

如何表达 function 的签名, 必须 return 它接收到的参数(或 this)(是调用),在 TypeScript 中? 是否有一种编程语言可以做到这一点?*

// In TypeScript (or consider it pseudo-code)
class C {
  // EXAMPLE 1 – Not polymorphic
  chainable(x): this                 // MUST not only return some C,
  {}                                 // but the same instance it was called on
}
// EXAMPLE 2
function mutate<T>(a: T[], x): T[]   // MUST return a, not a new Array
{
  /* So that this doesn't compile */ return Array.from(a);
  /* But this is OK */               return a;
}

相反,function 必须 return 一个新实例怎么样?

// EXAMPLE 3
function slice<T>(a: T[], x, y): T[] // MUST return a new Array

❌TypeScript


去 2?

下面的contract能达到上面的效果吗?

contract referentiallyIdentical(f F, p P) {
  f(p) == p
  v := *p
}
type returnsSameIntSlice(type T, *[]int referentiallyIdentical) T
func main() {
  var mutate returnsSameIntSlice = func(a *[]int) *[]int {
    b := []int{2}
    /* Would this compile? */ return &b
    /* This should */         return a
  }
}  

C++20?

上面可以用C++表达吗concept?


✅Scala


*最初,问题是关于在 TypeScript 中执行此操作,但由于这是不可能的,所以我很好奇它是否使用另一种语言。

如果该语言的类型系统无法表达,请随时删除标签

你可以 - 在 Scala 中。

Class 方法 returning this.type:

class C {
  var x = 0 

  /** Sets `x` to new value `i`, returns the same instance. */
  def with_x(i: Int): this.type = {
    x = i
    this   // must be `this`, can't be arbitrary `C`
  } 
}

就地排序保证 return 完全相同的数组(这里没有真正排序任何东西):

def sortInPlace[A: Ordered](arr: Array[A]): arr.type = {
  /* do fancy stuff with indices etc. */
  arr
}

如果您尝试 return 不同的数组,

def badSortInPlace(arr: Array[Int]): arr.type = Array(1, 2, 3) // won't compile

编译时会报错:

error: type mismatch;
found   : Array[Int]
required: arr.type
      def badSortInPlace(arr: Array[Int]): arr.type = Array(1, 2, 3)
                                                           ^

这叫做singleton type, and is explained in the spec

在具有参数多态性的语言中,

类型的任何函数
a → a

必须是恒等函数:由于函数在a中是多态的,它不可能知道关于a的任何事情,特别是,它不能可能知道如何构建 a。由于它也不采用世界值或 IO monad 或等价物,因此它无法从全局状态、数据库、网络、存储或终端获取值。它也不能删除该值,因为它必须 return 一个 a.

因此,它唯一能做的就是 return 传入的 a