G Goat Language

Стандартная библиотека

Полный справочник встроенных функций и типов. Функции из Builtins реализованы на F#; функции из Stdlib написаны на самом Goat.

Весь stdlib доступен без импорта — он загружается автоматически при старте интерпретатора.

Тип Option

Представляет необязательное значение. Определён в stdlib:

type Option =
  | None
  | Some of x
let present = Some 42
let absent  = None

match present with
| None   => "ничего"
| Some x => "есть: " ++ show x

Тип Result

Представляет успех или ошибку:

type Result =
  | Ok  of x
  | Err of e
fun divide x y =
  if y == 0 then Err "division by zero"
  else Ok (x / y)

match (divide 10 2) with
| Ok v  => show v
| Err e => "Ошибка: " ++ e

IO — Вывод

println : String -> IO ()

Выводит строку с переводом строки.

do! println "Hello, world!"
do! println (show 42)
print : String -> IO ()

Выводит строку без перевода строки.

do! print "Введите значение: "
show : a -> String

Преобразует любое значение в его строковое представление.

show 42         -- "42"
show true       -- "true"
show [1, 2, 3]  -- "[1, 2, 3]"
show (1, "a")  -- "(1, \"a\")"

IO — Ввод

input : IO String

Читает одну строку из stdin.

let! line = input
do! println ("Вы ввели: " ++ line)
getArgs : IO [String]

Возвращает аргументы командной строки.

let! args = getArgs
do! println (show args)

IO — Файлы

readFile : String -> IO String

Читает всё содержимое файла. Бросает ошибку, если файл не найден.

let! content = readFile "data.txt"
do! println content
writeFile : String -> String -> IO ()

Записывает строку в файл, перезаписывая содержимое.

do! writeFile "out.txt" "Hello!\n"
appendFile : String -> String -> IO ()

Дописывает строку в конец файла.

do! appendFile "log.txt" "новая строка\n"
fileExists : String -> IO Bool

Проверяет существование файла.

let! exists = fileExists "config.txt"
do! if exists then println "есть" else println "нет"

IO — Система

exit : Int -> IO ()

Завершает процесс с указанным кодом выхода.

do! exit 0   -- успех
do! exit 1   -- ошибка

Строки — Информация

strLength : String -> Int

Длина строки в символах.

strLength "hello"  -- 5
contains : String -> String -> Bool

Проверяет, содержит ли строка подстроку.

contains "hello world" "world"  -- true
contains "abc" "xyz"           -- false

Строки — Разбор

chars : String -> [String]

Разбивает строку на список символов (каждый — строка длины 1).

chars "abc"  -- ["a", "b", "c"]
words : String -> [String]

Разбивает строку на слова по пробелам и табуляциям.

words "hello world  foo"  -- ["hello", "world", "foo"]
lines : String -> [String]

Разбивает строку на строки по символам \n и \r.

lines "line1\nline2\nline3"  -- ["line1", "line2", "line3"]

Строки — Преобразование

trim : String -> String

Удаляет пробельные символы с обоих концов строки.

toUpper : String -> String

Переводит строку в верхний регистр.

toUpper "hello"  -- "HELLO"
toLower : String -> String

Переводит строку в нижний регистр.

toLower "HELLO"  -- "hello"
replace : String -> String -> String -> String

Заменяет все вхождения подстроки. replace строка старое новое.

replace "hello world" "world" "Goat"  -- "hello Goat"
unwords : [String] -> String

Объединяет список слов через пробел.

unwords ["hello", "world"]  -- " hello world" (с ведущим пробелом)
unlines : [String] -> String

Объединяет список строк через \n.

unlines ["a", "b", "c"]  -- "a\nb\nc\n"

Строки — Парсинг

parseInt : String -> Option Int

Парсит строку как целое число. Возвращает Some n или None.

parseInt "42"   -- Some 42
parseInt "abc"  -- None
parseFloat : String -> Option Float

Парсит строку как число с плавающей точкой.

parseFloat "3.14"  -- Some 3.14
parseFloat "x"     -- None

Математика — Основные

ФункцияТипОписание
abs xNum → NumАбсолютное значение
max a bNum → Num → NumМаксимум
min a bNum → Num → NumМинимум
sqrt xNum → FloatКвадратный корень
floor xNum → FloatОкругление вниз
ceil xNum → FloatОкругление вверх
round xNum → FloatОкругление к ближайшему
exp xNum → Floatex
log xNum → FloatНатуральный логарифм
log2 xNum → FloatЛогарифм по основанию 2
log10 xNum → FloatДесятичный логарифм

Математика — Тригонометрия

ФункцияОписание
sin xСинус (в радианах)
cos xКосинус
tan xТангенс

Математика — Конвертация

toFloat : Int -> Float

Конвертирует Int в Float.

toFloat 42  -- 42.0
toInt : Float -> Int

Конвертирует Float в Int (усечение).

toInt 3.9  -- 3

Математика — Константы

ИмяЗначениеОписание
pi3.14159265358979…Число π
e2.71828182845904…Число Эйлера

Списки — Базовые

ФункцияТипОписание
head xs[a] → aПервый элемент; ошибка на пустом
tail xs[a] → [a]Все элементы кроме первого
last xs[a] → aПоследний элемент
init xs[a] → [a]Все элементы кроме последнего
length xs[a] → IntДлина списка
null xs[a] → BoolПуст ли список
nth n xsInt → [a] → aЭлемент по индексу (0-based)
reverse xs[a] → [a]Обратный порядок
sort xs[a] → [a]Сортировка (Int, Float, String)
append xs ys[a] → [a] → [a]Конкатенация двух списков
concat xss[[a]] → [a]Сплющивание списка списков

Списки — Функции высшего порядка

map : (a -> b) -> [a] -> [b]

Применяет функцию к каждому элементу.

map (\x -> x * 2) [1, 2, 3]  -- [2, 4, 6]
filter : (a -> Bool) -> [a] -> [a]

Оставляет только элементы, удовлетворяющие предикату.

filter (\x -> x mod 2 == 0) [1..6]  -- [2, 4, 6]
fold : (acc -> a -> acc) -> acc -> [a] -> acc

Свёртка слева (foldl). Обрабатывает элементы слева направо.

fold (\acc x -> acc + x) 0 [1..5]   -- 15
fold (\acc x -> acc * x) 1 [1..5]   -- 120
foldr : (a -> acc -> acc) -> acc -> [a] -> acc

Свёртка справа (foldr). Обрабатывает элементы справа налево.

foldr (\x acc -> x :: acc) [] [1, 2, 3]  -- [1, 2, 3]
concatMap : (a -> [b]) -> [a] -> [b]

Применяет функцию и сплющивает результат (flatMap).

concatMap (\x -> [x, x * 2]) [1, 2, 3]  -- [1, 2, 2, 4, 3, 6]
zipWith : (a -> b -> c) -> [a] -> [b] -> [c]

Попарно применяет бинарную функцию к двум спискам.

zipWith (\a b -> a + b) [1, 2, 3] [4, 5, 6]  -- [5, 7, 9]
scan : (acc -> a -> acc) -> acc -> [a] -> [acc]

Как fold, но возвращает список всех промежуточных аккумуляторов.

scan (\acc x -> acc + x) 0 [1, 2, 3]  -- [0, 1, 3, 6]
ФункцияТипОписание
any pred xs(a→Bool)→[a]→BoolСуществует ли хоть один элемент, удовлетворяющий предикату
all pred xs(a→Bool)→[a]→BoolВсе ли элементы удовлетворяют предикату
elem x xsa→[a]→BoolСодержится ли элемент в списке

Списки — Трансформация

ФункцияОписание
take n xsПервые n элементов
drop n xsВсе элементы после первых n
takeWhile pred xsЭлементы с начала, пока выполняется предикат
dropWhile pred xsПропустить элементы с начала, пока выполняется предикат
zip xs ysОбъединить в список пар
unzip pairsРазделить список пар на два списка
replicate n xСписок из n копий x
range lo hiСписок целых от lo до hi включительно

Ленивые списки

lazyFilter : (a -> Bool) -> [a] -> [a]

Фильтр для ленивых (возможно бесконечных) списков. Хвост форсируется по требованию.

let evens = lazyFilter (\x -> x mod 2 == 0) nats
let first5 = take 5 evens  -- [0, 2, 4, 6, 8]
iterate : (a -> a) -> a -> [a]

Бесконечный список: x, f(x), f(f(x)), …

take 5 (iterate (\x -> x * 2) 1)  -- [1, 2, 4, 8, 16]
repeat : a -> [a]

Бесконечный список из одного повторяющегося значения.

take 4 (repeat 0)  -- [0, 0, 0, 0]
natsFrom : Int -> [Int]    nats : [Int]

Бесконечный поток натуральных чисел, начиная с n (или с 0 для nats).

take 5 (natsFrom 10)  -- [10, 11, 12, 13, 14]
take 5 nats           -- [0, 1, 2, 3, 4]

Option-комбинаторы

ФункцияТипОписание
mapOption f opt(a→b)→Option a→Option bПрименить функцию к содержимому, если Some
bindOption opt fOption a→(a→Option b)→Option bМонадическая цепочка
fromMaybe def opta→Option a→aЗначение или умолчание при None
isNone optOption a→BoolЯвляется ли None
isSome optOption a→BoolЯвляется ли Some
let result =
  bindOption (safeDivide 100 4) (\q ->
  bindOption (safeSqrt q) (\r ->
  Some (show r)))

let val = fromMaybe "N/A" result  -- "5.0" или "N/A"

Result-комбинаторы

ФункцияТипОписание
mapOk f r(a→b)→Result a e→Result b eПрименить функцию к Ok, Err пропустить
bindOk r fResult a e→(a→Result b e)→Result b eМонадическая цепочка по успешному пути

Функциональные утилиты

ФункцияТипОписание
id xa→aТождественная функция
const x _a→b→aВсегда возвращает первый аргумент
flip f x y(a→b→c)→b→a→cМеняет порядок аргументов
compose f g x(b→c)→(a→b)→a→cКомпозиция функций: f(g(x))
fix f((a→b)→a→b)→a→bНеподвижная точка (Y-комбинатор)
let double    = \x -> x * 2
let addOne    = \x -> x + 1
let doubleThenAdd = compose addOne double
let r = doubleThenAdd 5  -- 11

let always42 = const 42
let xs = map always42 [1..5]  -- [42, 42, 42, 42, 42]

let flippedDiv = flip (\a b -> a / b)
let half = flippedDiv 2  -- функция x -> x / 2