# This module provides common list operations.

# Get the first element in a list. If a list is empty, it returns a fallback value.
First = \(xs [any], fallback any) any {
  if [x, ..._] = xs {
    x()
  } else {
    fallback
  }
}

# Get the last element in a list. If a list is empty, it returns a fallback value.
Last = \(xs [any], fallback any) any {
  if [x, ...xs] = xs {
    last(xs, x)
  } else {
    fallback
  }
}

last = \(xs [any], x \() any) any {
  if [x, ...xs] = xs {
    last(xs, x)
  } else {
    x()
  }
}

# Convert a list of an `any` type to one of a `number` type skipping non-`number` types.
ToNumbers = \(xs [any]) [number] {
  if [x, ...xs] = xs {
    if x = x() as number {
      [number x, ...ToNumbers(xs)]
    } else {
      ToNumbers(xs)
    }
  } else {
    [number]
  }
}

# Convert a list of an `any` type to one of a `string` type skipping non-`string` types.
ToStrings = \(xs [any]) [string] {
  if [x, ...xs] = xs {
    if x = x() as string {
      [string x, ...ToStrings(xs)]
    } else {
      ToStrings(xs)
    }
  } else {
    [string]
  }
}

# Convert a list of an `any` type to one of a `boolean` type skipping non-`boolean` types.
ToBooleans = \(xs [any]) [boolean] {
  if [x, ...xs] = xs {
    if x = x() as boolean {
      [boolean x, ...ToBooleans(xs)]
    } else {
      ToBooleans(xs)
    }
  } else {
    [boolean]
  }
}