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

时间:2019-02-07 21:13:16

标签: scala go flowtype type-systems

在TypeScript中,如何必须返回其收到(调用)的参数(或function)的this的签名是否有可能的编程语言?*

// 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怎么样?

// 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吗?


✅斯卡拉


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

如果该语言的类型系统无法表达此标签,则可以随意删除该标签

2 个答案:

答案 0 :(得分:4)

您可以-在Scala中。

具有返回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`
  } 
}

就地排序可确保返回完全相同的数组(此处实际上不对任何内容排序):

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

如果您尝试返回其他数组,

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

答案 1 :(得分:1)

在具有参数多态性的语言中,任何类型的函数

a → a

必须是身份函数:由于该函数在a中是多态的,因此它可能不了解有关a的任何信息,尤其是,它可能不知道如何构造a。由于它也没有世界值或IO monad或类似值,因此它无法从全局状态,数据库,网络,存储或终端中获取值。它也不能删除该值,因为它必须返回一个a

Ergo,它唯一能做的就是返回传入的a