aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Bullard <anthony.bullard@gmail.com>2020-03-11 20:22:38 -0500
committerLouis Pilfold <louis@lpil.uk>2020-03-21 17:34:22 +0000
commit2379ccae323a920eeb2a7ed3df5f2a86280f02d0 (patch)
treeb273a2237be475c3500abdb4e2e4fe8414744681
parentdab126afc10e9b1333e365d67dd98d40c77b6f61 (diff)
downloadgleam_stdlib-2379ccae323a920eeb2a7ed3df5f2a86280f02d0.tar.gz
gleam_stdlib-2379ccae323a920eeb2a7ed3df5f2a86280f02d0.zip
Proposed string module docs. Types for other modules
-rw-r--r--gen/src/gleam@list.erl4
-rw-r--r--gen/src/gleam@string.erl27
-rw-r--r--src/gleam/atom.gleam1
-rw-r--r--src/gleam/dynamic.gleam3
-rw-r--r--src/gleam/list.gleam2
-rw-r--r--src/gleam/map.gleam1
-rw-r--r--src/gleam/string.gleam368
7 files changed, 379 insertions, 27 deletions
diff --git a/gen/src/gleam@list.erl b/gen/src/gleam@list.erl
index 57789ff..5706993 100644
--- a/gen/src/gleam@list.erl
+++ b/gen/src/gleam@list.erl
@@ -258,8 +258,8 @@ intersperse(List, Elem) ->
[_] ->
List;
- [X | Rest] ->
- [X, Elem | intersperse(Rest, Elem)]
+ [X1 | Rest] ->
+ [X1, Elem | intersperse(Rest, Elem)]
end.
at(List, Index) ->
diff --git a/gen/src/gleam@string.erl b/gen/src/gleam@string.erl
index 5d85771..eef6f5e 100644
--- a/gen/src/gleam@string.erl
+++ b/gen/src/gleam@string.erl
@@ -1,11 +1,28 @@
-module(gleam@string).
-compile(no_auto_import).
--export([length/1, lowercase/1, uppercase/1, compare/2, reverse/1, split/2, replace/3, append/2, concat/1, join/2]).
+-export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, split/2, append/2, concat/1, join/2]).
+
+is_empty(Str) ->
+ case Str of
+ <<"">> ->
+ true;
+
+ _ ->
+ false
+ end.
length(A) ->
string:length(A).
+reverse(String) ->
+ gleam@iodata:to_string(gleam@iodata:reverse(gleam@iodata:new(String))).
+
+replace(String, Pattern, Substitute) ->
+ gleam@iodata:to_string(
+ gleam@iodata:replace(gleam@iodata:new(String), Pattern, Substitute)
+ ).
+
lowercase(A) ->
string:lowercase(A).
@@ -15,20 +32,12 @@ uppercase(A) ->
compare(A, B) ->
gleam_stdlib:compare_strings(A, B).
-reverse(String) ->
- gleam@iodata:to_string(gleam@iodata:reverse(gleam@iodata:new(String))).
-
split(X, Pattern) ->
gleam@list:map(
gleam@iodata:split(gleam@iodata:new(X), Pattern),
fun gleam@iodata:to_string/1
).
-replace(String, Pattern, Substitute) ->
- gleam@iodata:to_string(
- gleam@iodata:replace(gleam@iodata:new(String), Pattern, Substitute)
- ).
-
append(First, Second) ->
gleam@iodata:to_string(
gleam@iodata:append(gleam@iodata:new(First), Second)
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 {}