Как мне объявить сигнатуру функции, которая должна возвращать один из ее аргументов?(на любом языке *) - PullRequest
0 голосов
/ 08 февраля 2019

Как можно выразить подпись для function, который должен вернуть аргумент (или 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, который должен вернуть новый экземпляр?

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

yTypeScript


Go 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?


alaScala


* Первоначально вопрос был о том, как это сделатьв TypeScript, но так как это невозможно, мне любопытно, если это на другом языке.

Не стесняйтесь удалять тег, если система типов этого языка не может выразить это

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

На языке с параметрическим полиморфизмом любая функция типа

a → a

должна быть тождественной функцией: так как функция полиморфна в a, она не может знатьЧто-нибудь о a, в частности, он не может знать, как создать a.Так как он также не принимает мировое значение или IO монаду или что-то эквивалентное, он не может получить значение из глобального состояния, базы данных, сети, хранилища или терминала.Он также не может сбросить значение, так как он должен возвращать a.

Ergo, единственное, что он может сделать, это вернуть a, который был передан.

0 голосов
/ 08 февраля 2019

Вы можете - в 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)
                                                           ^

Это называется одноэлементным типом и объясняется в спецификации .

...