diff --git a/stdlib/collections.affine b/stdlib/collections.affine index 48bb3ef..bcf77d5 100644 --- a/stdlib/collections.affine +++ b/stdlib/collections.affine @@ -26,7 +26,7 @@ pub fn reverse(list: [T]) -> [T] { } /// Take first n elements from list -fn take(n: Int, list: [T]) -> [T] { +pub fn take(n: Int, list: [T]) -> [T] { if n <= 0 || len(list) == 0 { [] } else { @@ -35,7 +35,7 @@ fn take(n: Int, list: [T]) -> [T] { } /// Drop first n elements from list -fn drop(n: Int, list: [T]) -> [T] { +pub fn drop(n: Int, list: [T]) -> [T] { if n <= 0 { list } else if len(list) == 0 { @@ -46,7 +46,7 @@ fn drop(n: Int, list: [T]) -> [T] { } /// Zip two lists together -fn zip(xs: [A], bs: [B]) -> [(A, B)] { +pub fn zip(xs: [A], bs: [B]) -> [(A, B)] { if len(xs) == 0 || len(bs) == 0 { [] } else { @@ -55,7 +55,7 @@ fn zip(xs: [A], bs: [B]) -> [(A, B)] { } /// Unzip a list of pairs -fn unzip(pairs: [(A, B)]) -> ([A], [B]) { +pub fn unzip(pairs: [(A, B)]) -> ([A], [B]) { let mut xs = []; let mut bs = []; for (a, b) in pairs { @@ -66,7 +66,7 @@ fn unzip(pairs: [(A, B)]) -> ([A], [B]) { } /// Find first element matching predicate -fn find(pred: T -> Bool, list: [T]) -> Option { +pub fn find(pred: T -> Bool, list: [T]) -> Option { for x in list { if pred(x) { return Some(x); @@ -76,7 +76,7 @@ fn find(pred: T -> Bool, list: [T]) -> Option { } /// Check if any element matches predicate -fn any(pred: T -> Bool, list: [T]) -> Bool { +pub fn any(pred: T -> Bool, list: [T]) -> Bool { for x in list { if pred(x) { return true; @@ -86,7 +86,7 @@ fn any(pred: T -> Bool, list: [T]) -> Bool { } /// Check if all elements match predicate -fn all(pred: T -> Bool, list: [T]) -> Bool { +pub fn all(pred: T -> Bool, list: [T]) -> Bool { for x in list { if !pred(x) { return false; @@ -96,7 +96,7 @@ fn all(pred: T -> Bool, list: [T]) -> Bool { } /// Partition list into two lists based on predicate -fn partition(pred: T -> Bool, list: [T]) -> ([T], [T]) { +pub fn partition(pred: T -> Bool, list: [T]) -> ([T], [T]) { let mut trues = []; let mut falses = []; for x in list { @@ -110,7 +110,7 @@ fn partition(pred: T -> Bool, list: [T]) -> ([T], [T]) { } /// Group consecutive equal elements -fn group(list: [T]) -> [[T]] { +pub fn group(list: [T]) -> [[T]] { if len(list) == 0 { [] } else { @@ -122,7 +122,7 @@ fn group(list: [T]) -> [[T]] { } /// Remove duplicate elements (requires Eq) -fn unique(list: [T]) -> [T] { +pub fn unique(list: [T]) -> [T] { if len(list) == 0 { [] } else { @@ -134,7 +134,7 @@ fn unique(list: [T]) -> [T] { } /// Intersperse element between all elements of list -fn intersperse(sep: T, list: [T]) -> [T] { +pub fn intersperse(sep: T, list: [T]) -> [T] { if len(list) <= 1 { list } else { @@ -143,7 +143,7 @@ fn intersperse(sep: T, list: [T]) -> [T] { } /// Concatenate list of lists -fn concat(lists: [[T]]) -> [T] { +pub fn concat(lists: [[T]]) -> [T] { let mut result = []; for list in lists { result = result ++ list; @@ -152,7 +152,7 @@ fn concat(lists: [[T]]) -> [T] { } /// Flat map (map then concat) -fn flat_map(f: A -> [B], list: [A]) -> [B] { +pub fn flat_map(f: A -> [B], list: [A]) -> [B] { concat(map(list, f)) } @@ -161,7 +161,7 @@ fn flat_map(f: A -> [B], list: [A]) -> [B] { // ============================================================================ /// Fill array with value -fn array_fill(size: Int, value: T) -> [T] { +pub fn array_fill(size: Int, value: T) -> [T] { let mut arr = []; let mut i = 0; while i < size { @@ -172,7 +172,7 @@ fn array_fill(size: Int, value: T) -> [T] { } /// Array from range -fn range(start: Int, end: Int) -> [Int] { +pub fn range(start: Int, end: Int) -> [Int] { if start >= end { [] } else { @@ -181,7 +181,7 @@ fn range(start: Int, end: Int) -> [Int] { } /// Array from range with step -fn range_step(start: Int, end: Int, step: Int) -> [Int] { +pub fn range_step(start: Int, end: Int, step: Int) -> [Int] { if step <= 0 || start >= end { [] } else { @@ -194,7 +194,7 @@ fn range_step(start: Int, end: Int, step: Int) -> [Int] { // ============================================================================ /// Sort list (requires Ord) -fn sort(list: [T]) -> [T] { +pub fn sort(list: [T]) -> [T] { if len(list) <= 1 { list } else { @@ -207,7 +207,7 @@ fn sort(list: [T]) -> [T] { } /// Binary search in sorted array -fn binary_search(target: T, arr: [T]) -> Option { +pub fn binary_search(target: T, arr: [T]) -> Option { binary_search_helper(target, arr, 0, len(arr)) } @@ -232,21 +232,21 @@ fn binary_search_helper(target: T, arr: [T], low: Int, high: Int) -> Option(a: [T], b: [T]) -> [T] { +pub fn set_union(a: [T], b: [T]) -> [T] { unique(a ++ b) } /// Intersection of two sets -fn set_intersection(a: [T], b: [T]) -> [T] { +pub fn set_intersection(a: [T], b: [T]) -> [T] { filter(a, fn(x) => any(fn(y) => x == y, b)) } /// Difference of two sets -fn set_difference(a: [T], b: [T]) -> [T] { +pub fn set_difference(a: [T], b: [T]) -> [T] { filter(a, fn(x) => !any(fn(y) => x == y, b)) } /// Check if element is in set -fn set_member(x: T, set: [T]) -> Bool { +pub fn set_member(x: T, set: [T]) -> Bool { any(fn(y) => x == y, set) } diff --git a/stdlib/string.affine b/stdlib/string.affine index 8e6996d..e091446 100644 --- a/stdlib/string.affine +++ b/stdlib/string.affine @@ -26,12 +26,12 @@ use prelude::{ Option, Some, None }; // ============================================================================ /// Check if string is empty -fn is_empty(s: String) -> Bool { +pub fn is_empty(s: String) -> Bool { len(s) == 0 } /// Get character at index, returning None for out-of-bounds access -fn char_at(s: String, idx: Int) -> Option { +pub fn char_at(s: String, idx: Int) -> Option { if idx >= 0 && idx < len(s) { Some(string_get(s, idx)) } else { @@ -41,7 +41,7 @@ fn char_at(s: String, idx: Int) -> Option { /// Get the length of a string (alias for len) /// Conforms to aLib string/length spec v1.0 -fn length(s: String) -> Int { +pub fn length(s: String) -> Int { len(s) } @@ -58,7 +58,7 @@ fn length(s: String) -> Int { // ============================================================================ /// Check if string starts with the given prefix -fn starts_with(s: String, prefix: String) -> Bool { +pub fn starts_with(s: String, prefix: String) -> Bool { let plen = len(prefix); if plen > len(s) { false @@ -68,7 +68,7 @@ fn starts_with(s: String, prefix: String) -> Bool { } /// Check if string ends with the given suffix -fn ends_with(s: String, suffix: String) -> Bool { +pub fn ends_with(s: String, suffix: String) -> Bool { let slen = len(s); let sfxlen = len(suffix); if sfxlen > slen { @@ -79,12 +79,12 @@ fn ends_with(s: String, suffix: String) -> Bool { } /// Check if string contains a substring -fn contains(s: String, substr: String) -> Bool { +pub fn contains(s: String, substr: String) -> Bool { string_find(s, substr) >= 0 } /// Find the first index of a substring, or -1 if not found -fn index_of(s: String, substr: String) -> Int { +pub fn index_of(s: String, substr: String) -> Int { string_find(s, substr) } @@ -94,13 +94,13 @@ fn index_of(s: String, substr: String) -> Int { /// Concatenate two strings /// Conforms to aLib string/concat spec v1.0 -fn concat(a: String, b: String) -> String { +pub fn concat(a: String, b: String) -> String { a ++ b } /// Extract substring from start (inclusive) to end (exclusive) /// Conforms to aLib string/substring spec v1.0 -fn substring(s: String, start: Int, end: Int) -> String { +pub fn substring(s: String, start: Int, end: Int) -> String { let slen = len(s); let clamped_start = if start < 0 { 0 } else if start > slen { slen } else { start }; let clamped_end = if end < clamped_start { clamped_start } else if end > slen { slen } else { end }; @@ -108,7 +108,7 @@ fn substring(s: String, start: Int, end: Int) -> String { } /// Repeat a string n times -fn repeat(s: String, n: Int) -> String { +pub fn repeat(s: String, n: Int) -> String { let mut result = ""; let mut i = 0; while i < n { @@ -169,12 +169,12 @@ pub fn join(arr: [String], separator: String) -> String { } /// Replace all occurrences of `from` with `to_str` in a string -fn replace(s: String, from: String, to_str: String) -> String { +pub fn replace(s: String, from: String, to_str: String) -> String { join(split(s, from), to_str) } /// Reverse a string -fn reverse_string(s: String) -> String { +pub fn reverse_string(s: String) -> String { let slen = len(s); let mut result = ""; let mut i = slen - 1; @@ -186,7 +186,7 @@ fn reverse_string(s: String) -> String { } /// Pad a string on the left to reach a target length -fn pad_left(s: String, target_len: Int, pad_char: String) -> String { +pub fn pad_left(s: String, target_len: Int, pad_char: String) -> String { let slen = len(s); if slen >= target_len { s @@ -196,7 +196,7 @@ fn pad_left(s: String, target_len: Int, pad_char: String) -> String { } /// Pad a string on the right to reach a target length -fn pad_right(s: String, target_len: Int, pad_char: String) -> String { +pub fn pad_right(s: String, target_len: Int, pad_char: String) -> String { let slen = len(s); if slen >= target_len { s @@ -219,24 +219,24 @@ fn pad_right(s: String, target_len: Int, pad_char: String) -> String { // ============================================================================ /// Check if character is an ASCII digit (0-9) -fn is_digit(c: Char) -> Bool { +pub fn is_digit(c: Char) -> Bool { let code = char_to_int(c); code >= 48 && code <= 57 } /// Check if character is an ASCII letter (a-z, A-Z) -fn is_alpha(c: Char) -> Bool { +pub fn is_alpha(c: Char) -> Bool { let code = char_to_int(c); (code >= 65 && code <= 90) || (code >= 97 && code <= 122) } /// Check if character is alphanumeric -fn is_alphanumeric(c: Char) -> Bool { +pub fn is_alphanumeric(c: Char) -> Bool { is_digit(c) || is_alpha(c) } /// Check if character is ASCII whitespace (space, tab, newline, carriage return) -fn is_whitespace(c: Char) -> Bool { +pub fn is_whitespace(c: Char) -> Bool { let code = char_to_int(c); code == 32 || code == 9 || code == 10 || code == 13 }