diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/atom.gleam | 1 | ||||
-rw-r--r-- | src/gleam/dynamic.gleam | 3 | ||||
-rw-r--r-- | src/gleam/list.gleam | 2 | ||||
-rw-r--r-- | src/gleam/map.gleam | 1 | ||||
-rw-r--r-- | src/gleam/string.gleam | 368 |
5 files changed, 359 insertions, 16 deletions
diff --git a/src/gleam/atom.gleam b/src/gleam/atom.gleam index 9b69127..74a05ad 100644 --- a/src/gleam/atom.gleam +++ b/src/gleam/atom.gleam @@ -10,7 +10,6 @@ pub external fn from_string(String) -> Result(Atom, AtomNotLoaded) = // This function can create a new atom if one does not already exist for // the given string. Atoms are not garbage collected so this can result // in a memory leak if called over time on new values -// pub external fn create_from_string(String) -> Atom = "gleam_stdlib" "atom_create_from_string"; diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index 298f864..68fe807 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -5,18 +5,15 @@ import gleam/result // `Dynamic` data is data that we don"t know the type of yet. // We likely get data like this from interop with Erlang, or from // IO with the outside world. -// pub external type Dynamic; // Convert any Gleam data into `Dynamic` data. -// pub external fn from(a) -> Dynamic = "gleam_stdlib" "identity"; // Unsafely cast a Dynamic value into any other type. // // This is an escape hatch for the type system that may be useful when wrapping // native Erlang APIs. It is to be used as a last measure only. -// pub external fn unsafe_coerce(a) -> b = "gleam_stdlib" "identity"; pub external fn string(from: Dynamic) -> Result(String, String) diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index 6ea102e..33cdf6c 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -8,11 +8,9 @@ pub type LengthMismatch { } // Using the Erlang C BIF implementation. -// pub external fn length(List(a)) -> Int = "erlang" "length" // Using the Erlang C BIF implementation. -// pub external fn reverse(List(a)) -> List(a) = "lists" "reverse" pub fn is_empty(list: List(a)) -> Bool { diff --git a/src/gleam/map.gleam b/src/gleam/map.gleam index 848d5a6..0b5595c 100644 --- a/src/gleam/map.gleam +++ b/src/gleam/map.gleam @@ -2,6 +2,7 @@ import gleam/result import gleam/list import gleam/result.{Option} +/// An Erlang map. See [the Erlang map module](https://erlang.org/doc/man/maps.html) for details pub external type Map(key, value); pub external fn size(Map(k, v)) -> Int diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam index 35abb44..b4cfa69 100644 --- a/src/gleam/string.gleam +++ b/src/gleam/string.gleam @@ -1,16 +1,53 @@ +/// A built-in representation for efficient string manipulation. String literals +/// are enclosed in `"double quotes"`. +/// import gleam/iodata import gleam/list import gleam/order + + + +/// ## Basics + + + + +/// Determine if a string is empty. +/// +/// ## Examples +/// ``` +/// > is_empty("") == True +/// > isEmpty("the world") == False +/// ``` +/// +pub fn is_empty(str: String) -> Bool { + case str { + "" -> True + _ -> False + } +} + + +/// Get the length of a +/// +/// > length("innumerable") == 11 +/// > length("") == 0 +/// pub external fn length(String) -> Int = "string" "length" -pub external fn lowercase(String) -> String = "string" "lowercase" -pub external fn uppercase(String) -> String = "string" "uppercase" +/// Repeat a string `n` times. +/// +/// > repeat(3, "ha") == "hahaha" +/// +// pub fn repeat(string: String, times: Int) -> String {} -pub external fn compare(String, String) -> order.Order = - "gleam_stdlib" "compare_strings" +/// Reverse a string. +/// +/// > reverse("stressed") == "desserts" +/// pub fn reverse(string: String) -> String { string |> iodata.new @@ -18,13 +55,11 @@ pub fn reverse(string: String) -> String { |> iodata.to_string } -pub fn split(string x: String, on pattern: String) -> List(String) { - x - |> iodata.new - |> iodata.split(_, on: pattern) - |> list.map(_, with: iodata.to_string) -} +/// Replace all occurrences of some substring. +/// +/// > replace("Json.Decode.succeed", all: ".", with: "-") == "Json-Decode-succeed" +/// > replace("a,b,c,d,e", all: ",", with: "/") == "a/b/c/d/e" pub fn replace( in string: String, all pattern: String, @@ -36,6 +71,135 @@ pub fn replace( |> iodata.to_string } + +/// Convert a string to all lower case. Useful for case-insensitive comparisons. +/// +/// > lowercase("X-FILES") == "x-files" +/// +pub external fn lowercase(String) -> String = "string" "lowercase" + + +/// Convert a string to all upper case. Useful for case-insensitive comparisons +/// and VIRTUAL YELLING. +/// +/// > uppercase("skinner") == "SKINNER" +/// +pub external fn uppercase(String) -> String = "string" "uppercase" + + +/// Determines the order of the two strings. +/// +/// > compare("Billy", "Anthony") == order.Gt +/// > compare("Anthony", "Billy") == order.Lt +/// > compare("Anthony", "Anthony") == order.Eq +/// +pub external fn compare(String, String) -> order.Order = + "gleam_stdlib" "compare_strings" + + + + + +/// ## Get Substrings + + + + +/// Take a substring given a start and end index. Negative indexes +/// are taken starting from the *end* of the list. +/// +/// > slice(start: 7, end: 9, "snakes on a plane!") == "on" +/// > slice(start: 0, end: 6, "snakes on a plane!") == "snakes" +/// > slice(start: 0, end: -7, "snakes on a plane!") == "snakes on a" +/// > slice(start: -6, end: -1, "snakes on a plane!") == "plane" +/// +// pub fn slice(string: String, start: Int, end: Int) -> String {} + + +/// Take *n* characters from the left side of a +/// +/// > left(num: 2, string: "Mulder") == "Mu" +/// +// pub fn left(from string: String, num n: Int) -> String {} + + +/// Take *n* characters from the right side of a +/// +/// > right("Scully", 2) == "ly" +/// +// pub fn right(from string: String, num_characters: Int) -> String {} + + +/// Drop *n* characters from the left side of a +/// +/// > dropLeft(from: "The Lone Gunmen", num_characters: 2) == "e Lone Gunmen" +/// +// pub fn drop_left(from string: String, num_characters: Int) -> String {} + + +/// Drop *n* characters from the right side of a +/// +/// > dropRight("Cigarette Smoking Man", 2) == "Cigarette Smoking M" +/// +// pub fn drop_right(from string: String, num_characters: Int) -> String {} + + + + +/// ## Check for Substrings + + + + +/// See if the second string contains the first one. +/// +/// > contains("theory", this: "the") == True +/// > contains("theory", this: "hat") == False +/// > contains("theory", this: "THE") == False +/// +// pub fn contains(this: String, in: String) -> String {} + + +/// See if the second string starts with the first one. +/// +/// > startsWith("theory", this: "the") == True +/// > startsWith("theory", this: "ory") == False +/// +// pub fn starts_with(this: String, in: String) -> String {} + + +/// See if the second string ends with the first one. +/// +/// > endsWith("theory", this: "the") == False +/// > endsWith("theory", this: "ory") == True +/// +// pub fn ends_with(this: String, in: String) -> String {} + + + + +/// ## Building and Splitting + + + + +/// Split a string using a given separator. +/// +/// > split("cat,dog,cow", on: ",") == ["cat","dog","cow"] +/// > split("home/evan/Desktop/", on: "/") == ["home","evan","Desktop", ""] +/// +pub fn split(string x: String, on pattern: String) -> List(String) { + x + |> iodata.new + |> iodata.split(_, on: pattern) + |> list.map(_, with: iodata.to_string) +} + + +/// Append two strings. +/// +/// > append(to: "butter", suffix: "fly") == "butterfly" +/// pub fn append(to first: String, suffix second: String) -> String { first |> iodata.new @@ -43,15 +207,199 @@ pub fn append(to first: String, suffix second: String) -> String { |> iodata.to_string } + +/// Concatenate many strings into one. +/// +/// > concat(["never","the","less"]) == "nevertheless" +/// pub fn concat(strings: List(String)) -> String { strings |> iodata.from_strings |> iodata.to_string } + +/// Put many strings together with a given separator. +/// +/// > join(["H","w","ii","n"], with: "a") == "Hawaiian" +/// > join(["cat","dog","cow"], with: " ") == "cat dog cow" +/// > join(["home","evan","Desktop"], with: "/") == "home/evan/Desktop" +/// pub fn join(strings: List(String), with separator: String) -> String { strings |> list.intersperse(_, with: separator) |> iodata.from_strings |> iodata.to_string } + + + +/// Break a string into words, splitting on chunks of whitespace. +/// +/// > words("How are \t you? \n Good?") == ["How","are","you?","Good?"] +/// +// pub fn words(string: String) -> List(String) {} + + +/// Break a string into lines, splitting on newlines. +/// +/// > lines("How are you?\nGood?") == ["How are you?", "Good?"] +/// +// pub fn lines(string: String): List(String) {} + + +/// Get all of the indexes for a substring in another +/// +/// > indexes(of: "i", in:"Mississippi") == [1,4,7,10] +/// > indexes(of: "ss", in: "Mississippi") == [2,5] +/// > indexes(of: "needle", in: "haystack") == [] +/// +// pub fn indexes(of: String, in: String) -> String {} + + + + +/// ## Formatting + + + + +/// Pad a string on both sides until it has a given length. +/// +/// > pad("1", to: 5, with: ' ') == " 1 " +/// > pad("11", to: 5, with: ' ') == " 11 " +/// > pad("121", to: 5, with: ' ') == " 121 " +/// +// pub fn pad(string: String, to size: Int, with: String) -> String {} + + +/// Pad a string on the left until it has a given length. +/// +/// > padLeft("1", to: 5, with: '.') == "....1" +/// > padLeft("11", to: 5, with: '.') == "...11" +/// > padLeft("121", to: 5, with: '.') == "..121" +/// +// pub fn pad_left(string: String, to size: Int, with: String) {} + + +/// Pad a string on the right until it has a given length. +/// +/// > padRight("1", to: 5, with: '.') == "1...." +/// > padRight("11", to: 5, with: '.') == "11..." +/// > padRight("121", to: 5, with: '.') == "121.." +/// +// pub fn pad_right(string: String, to size: Int, with: String) {} + + +/// Get rid of whitespace on both sides of a +/// +/// > trim(" hats \n") == "hats" +/// +// pub fn trim(string: String) -> String {} + + +/// Get rid of whitespace on the left of a +/// +/// > trimLeft(" hats \n") == "hats \n" +/// +// pub fn trim_left(string: String) -> String {} + + +/// Get rid of whitespace on the right of a +/// +/// > trimRight(" hats \n") == " hats" +/// +// pub fn trim_right(string: String) -> String {} + + + + + +/// ## List Conversions + + + + +// These functions convert to and from char, which currently +// does not exist as a type in Gleam. + +// /// Convert a string to a list of characters. +// /// +// /// > to_list("abc") == ['a','b','c'] +// /// +// pub fn to_list(string: String) -> List(String) {} + +// /// Convert a list of characters into a Can be useful if you +// /// want to create a string primarily by consing, perhaps for decoding +// /// something. +// /// +// /// > from_list(['a','b','c']) == "abc" +// /// +// // pub fn from_list(strings: List(String)) -> String {} + +// /// Add a character to the beginning of a string. +// /// +// /// > cons('T', onto: "he truth is out there") == "The truth is out there" +// // pub fn cons(char: Char, onto string: String) -> String {} + + +/// Split a non-empty string into its head and tail. This lets you +/// pattern match on strings exactly as you would with lists. +/// +/// > uncons("abc") == Ok(('a',"bc")) +/// > uncons("") == Error(Nil) +/// +// pub fn uncons(string: String) -> Result(tuple(String, String), Nil) {} + + + + +/// ## Higher-Order Functions + + + + +/// Transform every character in a string +/// +/// > map("a/b/c", with: replace(all: "/", with: ".")) == "a.b.c" +/// +// pub fn map(string: String, with: fn(String) -> String) -> String {} + + +/// Keep only the characters that pass the test. +/// +/// > filter("R2-D2", where: isDigit) == "22" +/// +// pub fn filter(string: String, where: fn(String) -> Bool) -> String {} + + +/// Reduce a string from the left. +/// +/// > foldl("time", into: "", with: append) == "emit" +/// +// pub fn foldl(string: String, into accumulator: b, with: fn(String, b) -> b) -> b {} + + +/// Reduce a string from the right. +/// +/// > foldr("time", into: "", with: append) == "time" +/// +// pub fn foldr(string: String, into accumulator: b, with: fn(String, b) -> b) -> b {} + + +/// Determine whether *any* characters pass the test. +/// +/// > any("90210", that: isDigit) == True +/// > any("R2-D2", that: isDigit) == True +/// > any("heart", that: isDigit) == False +/// +// pub fn any(string: String, that predicate: fn(String) -> Bool) -> Bool {} + + +/// Determine whether *all* characters pass the test. +/// +/// > all("90210", that: isDigit) == True +/// > all("R2-D2", that: isDigit) == False +/// > all("heart", that: isDigit) == False +/// +// pub fn all(string: String, that predicate: fn(String) -> Bool) -> Bool {} |