pine 🍍

Utility library for deno with an FP bent.

You should be able to pull all functions straight from mod like import { take } from "https://deno.land/x/pine/mod.ts"

I highly recommend looking at the test file for a function to see how to use it.

stability

Most of the api should be pretty stable, but for now I would pin a version as I am planning to rewrite some of the function implementations, and add things like automatic currying.

functions implemented so far:

add

add(x: number, y: number): number

Returns the numbers added together

add(2, 3) == 5

chunkEvery

chunkEvery<T>(count: number, list: T[]): T[][]

Chunks the list by count excess are thrown away

`chunkEvery(2, [1, 2, 3, 4, 5]) == [[1, 2], [3, 4]]

clamp

clamp(min: number, max: number, value: number): number

clamp(0, 10, 20) == 10

dec

dec(n: number): number

Returns one less than n

dec(3) == 2

enumerate

enumerate<T>(list: T[]): [number, T] []

Returns an array of tuples having the signature [index, item]

enumerate(['a', 'b', 'c']) == [[0, 'a'], [1, 'b'], [2, 'c']]

f

f(): boolean

Returns false

f() == false

filter

filter<T>(pred: (T) => bool, list: T[]): T[]

Returns all items in the list where T satisfies pred

filter(isEven, [1, 2, 3, 4]) == [2, 4]

first

first<T>(list: T[]): T[]

Returns all items in the array except the last one first([1, 2, 3]) == [1, 2]

flip

flip(fn: Function): Function

Takes a function with two parameters

Returns the function with the arguments reversed

fold

fold<T, U>(fn: (acc: U, x: T) => U, acc: U, list: T[]): U

Takes a reducer, an initial accumulator value, and a list of items. Applies the function on the accumulator, and each item of the list as it iterates through and returns the final accumulator.

fold(add, 0, [1, 2, 3]) == 6

frequencies

frequencies<T>(list: <T>): Map<T, number>

Returns a frequency table created from the list, in a Map data structure

frequencies([1, 1, 2, 2, 2], Map{ 1: 2, 2: 3})

hasKey

hasKey(key: keyof any, obj: Object): boolean

Returns wether the object has the given key

hasKey("x", {x: 1}) == true

head<T>(list: T[]): T

Returns the first item in a list

head([1, 2, 3]) == 1

identity

`identity(item: T): T1

Returns the item passed in

identity(5) == 5

inc

inc(n: number): number

Returns one higher than n

inc(1) == 2

indexMap

indexMap<T, U>(fn: (i: number, item: T) => U, list: T[]): U

Runs a function for every item in the list supplying the index, and the item as arguments

indexMap((i, item) => i + item, [5, 5, 5]) == [5, 6, 7]

isEmpty

isEmpty<T>(list: T[]): boolean

Returns wether the given list is empty

isEmpty([]) == true

isEven

isEven(n: number): boolean

Returns wether the given number is even isEven(2) == true

isOdd

isOdd(n: number): boolean

Returns wether the given number is odd isOdd(3) == true

last

last<T>(list: T[]): T

Returns the last item in a list last([1, 3, 2]) == 2

length

length<T>(list: T[]): number

Returns the length of the list

length([1, 1, 1]) == 3

map

map<T, U>(fn: T => U, list: T[]): U

Applies a function to each item in a list, returning a new list of the results of each call

mapGet

mapGet<K, V>(key: K, map: Map<K, V>): V

Returns the value for the key key on the map. Throws an error if the key is not found

mapHas

mapHas<K, V>(key: K, map: Map<K, V>): boolean

Returns whether a map has the given key

mapSet

mapSet<K, V>(key: K, value: V, Map<K, V>): Map<K, V>

Returns a new map based off the one passed in with the key key set to value

max

max(x: number, y: number): number

Returns the larger of two numbers

max(2, 4) == 4

maximum

max(list: number[]): number

Returns the largest item in the list

maximum([1, 2, 3]) = 3

min

min(x: number, y: number): number

Returns the smaller of two numbers

min(2, 4) == 2

minBy

`minBy(fn: (item: T) => T, x: T, y: T): T

Returns the smaller of originals from applying the function to both items

const first = { x: 4 }
const second = { x: 5}
minBy(o => o.x, first, second) == first

minimum

minimum(list: number[]): number

Returns the smallest item in the list

`minimum([1, 2, 3]) == 1

not

not(b: boolean): boolean

Returns the opposite of the applied boolean

not(true) == false

range

range(start: number, stop: number): number[]

Returns an array of numbers from start to stop inclusive

range(1, 3) == [1, 2, 3]

reduce

reduce<T>(fn: (x: T, y: T) => T, list: T[]): T

Shorthand for call to fold where the initial value is the first item of the list, and iterates through the rest of the list

reduce(add, [1, 2, 3]) == 6

repeat

repeat<T>(count: number, item: T): T[]

Returns an array of count length with item repeated

`repeat(3, "apple") == ["apple", "apple", "apple"]

reverse

reverse<T>(list: T[]): T[]

Returns the list in the reversed order

reverse([1, 2, 3]) == [3, 2, 1]

scan

scan<T, U>(fn: (x: T) => U, init: U, list: T[]): U[]

Iterates over the list in the same way as fold, but saves all steps along the way.

scan(add, 0, [1, 2, 3]) == [0, 1, 3, 6]

t

t(): boolean

Returns true t() == true

tail

tail<T>(list: T[]); T[]

Returns all items after the first in a list tail([1, 2, 3]) == [2, 3]

take

take<T>(count: number, list: T[]): T[]

Returns the first count items from a list

take(2, [1, 2, 3, 4, 5]) == [1, 2]

takeLast

takeLast<T>(count: number, list: T[]): T[]

Returns the last count items from a list

takeLast(2, [1, 2, 3, 4, 5]) == [4, 5]

takeWhile

takeWhile<T>(pred: (T) => boolean, list: T[]): T[]

Returns elements of the list until it first gets a false value from the predicate. Does not return the value that returned false

takeWhile(x => x < 2, [1, 1, 1, 3]) == [1, 1, 1]

zip

zip<T, U>(first: T[], second: U[]): [T, U][]

Zips two arrays together into an array of tuples. Extra items from the longer will be ignored

zip([1, 2, 3, 4], ["a", "b", "c"]) == [[1, "a"], [2, "b"], [3, "c"]]

TODO:

  • more tests
  • automatic currying
  • Option/Result types
  • more tests
  • more tests
  • better way to handle type of functions

Contribute?

Want to send a pr? I'm pretty open. If you're adding a new function, it needs to do three things:

  • be in a new file
  • have a matching test file
  • export from mod