functions.nim 2.9 KB
import sequtils

proc firstOfList*[T](): proc(list: seq[T]): T =
  # Returns a function that returns the first value of a seq.
  result = proc (list: seq[T]): T = list[0]

assert(firstOfList[int]()(@[1, 2]) == 1)

#  public static <T> Function<List<T>, T> firstOfList() {
#    return (list) -> list.get(0);
#  }

proc lastOfList*[T](): proc(list: seq[T]): T =
  # Returns a function that returns the last value of a seq.
  result = proc (list: seq[T]): T = list[high(list)]

assert(lastOfList[int]()(@[1, 2]) == 2)

#  public static <T> Function<List<T>, T> lastOfList() {
#    return (list) -> list.get(list.size() - 1);
#  }

proc nthOfList*[T](index: int): proc(list: seq[T]): T =
  ## Returns a function that returns the value at the given index. Negative indexes are counted from
  ## the end of the list.
  result = proc (list: seq[T]): T =
    if index < 0:
      result = list[list.len + index]
    else:
      result = list[index]

assert(nthOfList[int](1)(@[1, 2]) == 2)
assert(nthOfList[int](-1)(@[1, 2]) == 2)
assert(nthOfList[int](-2)(@[1, 2]) == 1)

#  public static <T> Function<List<T>, T> nthOfList(int index) {
#    return (list) -> list.get(index < 0 ? list.size() + index : index);
#  }

proc permutationOfList*[T](indexes: varargs[int]): proc(list: seq[T]): seq[T] =
  ## Returns a function that returns the permutation of a given list. Negative indexes are counted
  ## from the end of the list.
  let inds = @indexes # Copying varargs (an array) to a seq so that the proc below can capture it
  result = proc (list: seq[T]): seq[T] =
    newSeq(result, 0)
    for index in inds:
      if index < 0:
        result.add(list[list.len + index])
      else:
        result.add(list[index])

assert(permutationOfList[int](1,0)(@[1, 2]) == @[2, 1])
assert(permutationOfList[int](0,1)(@[1, 2]) == @[1, 2])

# public static <T> Function<List<T>, List<T>> permutationOfList(int... indexes) {
#    return (list) -> {
#      List<T> result = new ArrayList<>(indexes.length);
#      for (int index : indexes) {
#        result.add(list.get(index < 0 ? list.size() + index : index));
#      }
#      return result;
#    };
#  }

proc withoutSeparators*[T](): proc(list: seq[T]): seq[T] =
  ##  Returns a function that skips the separators of a given list.
  result = proc (list: seq[T]): seq[T] =
    newSeq(result, 0)
    for i in countup(0, high(list), 2):
      result.add(list[i])

#  public static <T> Function<List<T>, List<T>> withoutSeparators() {
#    return (list) -> {
#     List<T> result = new ArrayList<>();
#      for (int i = 0; i < list.size(); i += 2) {
#        result.add(list.get(i));
#      }
#      return result;
#    };
#  }

proc constant*[T,A](output: T): proc(input: A): T =
  ## Returns a function that returns a constant value.
  result = proc (input: A): T = output

#  public static <T> Function<Object, T> constant(T output) {
#    return (input) -> output;
#  }

  
assert(constant[string, string]("hey")("hy") == "hey")