core

A biblioteca fundamental: operações de lista, folds, auxiliares de ordem superior e conversões de tipo.

import core

A maioria dos programas começa por aqui. O core é escrito na própria Bern, então toda função abaixo é uma função Bern comum que você pode ler em lib/core.brn. Funções que percorrem uma lista a recebem como primeiro argumento, o que combina naturalmente com o operador pipe )|.

Transformando listas

map(lista, função) → lista

Aplica uma função a cada elemento, devolvendo uma nova lista com os resultados.

map([1, 2, 3], \x -> x * 2)
-- Saída: [2, 4, 6]
filter(lista, predicado) → lista

Mantém apenas os elementos para os quais o predicado retorna true.

filter([1, 2, 3, 4, 5], \x -> x % 2 == 0)
-- Saída: [2, 4]
reverse(coleção) → coleção

Inverte uma lista ou um conjunto; o tipo é detectado automaticamente.

reverse([1, 2, 3])
-- Saída: [3, 2, 1]

reverse({1, 2, 3})
-- Saída: {3, 2, 1}
append(lista, cauda) → lista

Concatena cauda ao fim de lista (o mesmo efeito de <>, na forma de função).

append([1, 2], [3, 4])
-- Saída: [1, 2, 3, 4]
range(início, fim) → lista

Constrói uma lista inclusiva de inteiros - um invólucro de função para a sintaxe [início..fim].

range(1, 5)
-- Saída: [1, 2, 3, 4, 5]

Folds & agregação

foldl(lista, acumulador, função) → valor

Reduz a lista da esquerda para a direita. A função recebe (acumulador, elemento).

foldl([1, 2, 3], 0, \acc, x -> acc + x)
-- Saída: 6
foldr(lista, acumulador, função) → valor

Reduz a lista da direita para a esquerda. A função recebe (elemento, acumulador), sendo a escolha natural quando você quer reconstruir uma lista a partir da direita.

foldr([1, 2, 3], [], \x, acc -> [x * 10] <> acc)
-- Saída: [10, 20, 30]
sum(lista) → número

Soma todos os elementos.

sum([1, 2, 3, 4])
-- Saída: 10
product(lista) → número

Multiplica todos os elementos.

product([1, 2, 3, 4])
-- Saída: 24
min(lista) → valor

O menor elemento. Gera erro em lista vazia.

min([4, 1, 7, 3])
-- Saída: 1
max(lista) → valor

O maior elemento. Gera erro em lista vazia.

max([4, 1, 7, 3])
-- Saída: 7

Fatiamento & acesso

take(n, lista) → lista

Os primeiros n elementos (ou a lista inteira, se ela for menor).

take(2, [10, 20, 30, 40])
-- Saída: [10, 20]
drop(n, lista) → lista

Tudo, exceto os primeiros n elementos.

drop(2, [10, 20, 30, 40])
-- Saída: [30, 40]
head(lista) → elemento

O primeiro elemento. Retorna um valor de erro em lista vazia.

head([10, 20, 30])
-- Saída: 10
tail(lista) → lista

Tudo, exceto o primeiro elemento.

tail([10, 20, 30])
-- Saída: [20, 30]

Predicados & busca

isEmpty(lista) → booleano

Se a lista não tem elementos.

isEmpty([])
-- Saída: true
isEmpty([1])
-- Saída: false
any(lista, predicado) → booleano

Pelo menos um elemento satisfaz o predicado?

any([1, 3, 5, 6], \x -> x % 2 == 0)
-- Saída: true
all(lista, predicado) → booleano

Todos os elementos satisfazem o predicado?

all([2, 4, 6], \x -> x % 2 == 0)
-- Saída: true
find(lista, predicado) → elemento | false

O primeiro elemento que casa, ou false quando nenhum casa.

find([1, 2, 3, 4], \x -> x > 2)
-- Saída: 3
find([1, 2], \x -> x > 9)
-- Saída: false
index_of(coleção, alvo) → int

O índice de alvo em uma lista ou conjunto, ou -1 se ausente.

index_of(['a', 'b', 'c'], 'b')
-- Saída: 1
index_of([1, 2, 3], 9)
-- Saída: -1

Combinando listas

zip(lista1, lista2) → lista

Pareia elementos por posição; para na lista mais curta.

zip([1, 2, 3], ['a', 'b', 'c'])
-- Saída: [[1, 'a'], [2, 'b'], [3, 'c']]
zipWith(lista1, lista2, função) → lista

Combina elementos por posição usando uma função de dois argumentos.

zipWith([1, 2, 3], [10, 20, 30], \a, b -> a + b)
-- Saída: [11, 22, 33]

Auxiliares de função

compose(f, g, x) → valor

Aplica g e depois f: compose(f, g, x) é f(g(x)).

compose(\x -> x + 1, \x -> x * 2, 5)
-- Saída: 11   (5 * 2, depois + 1)
id(x) → x

A função identidade - devolve seu argumento sem mudar. Útil como padrão ou marcador.

id(42)
-- Saída: 42
const(x, _) → x

Sempre devolve o primeiro argumento e ignora o segundo.

const(7, "ignorado")
-- Saída: 7
flip(f, x, y) → valor

Chama uma função de dois argumentos com os argumentos trocados.

flip(\a, b -> a - b, 3, 10)
-- Saída: 7   (10 - 3)

Conversões & introspecção

to_int(string) → int

Converte uma string de dígitos em um inteiro.

to_int("42")
-- Saída: 42
int_to_double(int) → double

Amplia um inteiro para um double.

int_to_double(5)
-- Saída: 5.0
char_to_digit(char) → int

Transforma um caractere de dígito em seu valor numérico (erro em não-dígito).

char_to_digit('7')
-- Saída: 7
typeOf(valor) → string

O tipo de um valor como string - a forma de função do operador ::.

typeOf([1, 2, 3])
-- Saída: "List"
length(valor) → int

O comprimento de uma string, lista ou conjunto - a forma de função do operador :>.

length("hello")
-- Saída: 5
is_error(valor) → booleano

Se um valor é um valor de erro recuperável.

is_error([1, 2, 3][99])
-- Saída: true
print(valor) → valor

Imprime um valor explicitamente (literais imprimem sozinhos, mas print é útil sob o pragma no-eval). Devolve o valor.

print("hello")
-- Saída: "hello"

Juntando tudo

As funções se compõem naturalmente. Aqui várias são encadeadas com o operador pipe para transformar uma lista de preços no total dos itens com desconto:

Um pequeno pipeline de dados

import core

prices = [12, 40, 7, 25, 3, 60]

-- mantém os acessíveis, aplica 10% de desconto e soma
total = prices
    )| filter(\p -> p <= 40)
    )| map(\p -> p - (p / 10))
    )| sum

total
-- Saída: 76   (12+40+7+25 = 84, menos 10% por item)

E um resumo clássico baseado em fold que reúne zip, foldl e max:

Rotulando a maior pontuação

import core

names  = ["Ana", "Bob", "Cia"]
scores = [88, 95, 73]

pairs = zip(names, scores)
-- [["Ana", 88], ["Bob", 95], ["Cia", 73]]

best = max(scores)
winner = find(pairs, \pair -> pair[1] == best)
winner[0] + " venceu com " + best
-- Saída: "Bob venceu com 95"