Idris2-boot/libs/base/Data/Strings.idr
2020-03-19 22:14:48 +00:00

188 lines
4.6 KiB
Idris

module Data.Strings
import Data.List
export
singleton : Char -> String
singleton c = strCons c ""
partial
foldr1 : (a -> a -> a) -> List a -> a
foldr1 _ [x] = x
foldr1 f (x::xs) = f x (foldr1 f xs)
partial
foldl1 : (a -> a -> a) -> List a -> a
foldl1 f (x::xs) = foldl f x xs
-- This works quickly because when string-append builds the result, it allocates
-- enough room in advance so there's only one allocation, rather than lots!
export
fastAppend : List String -> String
fastAppend xs = unsafePerformIO (schemeCall String "string-append" (toFArgs xs))
where
toFArgs : List String -> FArgList
toFArgs [] = []
toFArgs (x :: xs) = x :: toFArgs xs
||| Splits a character list into a list of whitespace separated character lists.
|||
||| ```idris example
||| words' (unpack " A B C D E ")
||| ```
words' : List Char -> List (List Char)
words' s = case dropWhile isSpace s of
[] => []
s' => let (w, s'') = break isSpace s'
in w :: words' s''
||| Splits a string into a list of whitespace separated strings.
|||
||| ```idris example
||| words " A B C D E "
||| ```
export
words : String -> List String
words s = map pack (words' (unpack s))
||| Joins the character lists by spaces into a single character list.
|||
||| ```idris example
||| unwords' [['A'], ['B', 'C'], ['D'], ['E']]
||| ```
unwords' : List (List Char) -> List Char
unwords' [] = []
unwords' ws = assert_total (foldr1 addSpace ws) where
addSpace : List Char -> List Char -> List Char
addSpace w s = w ++ (' ' :: s)
||| Joins the strings by spaces into a single string.
|||
||| ```idris example
||| unwords ["A", "BC", "D", "E"]
||| ```
export
unwords : List String -> String
unwords = pack . unwords' . map unpack
||| Splits a character list into a list of newline separated character lists.
|||
||| ```idris example
||| lines' (unpack "\rA BC\nD\r\nE\n")
||| ```
lines' : List Char -> List (List Char)
lines' s = case dropWhile isNL s of
[] => []
s' => let (w, s'') = break isNL s'
in w :: lines' s''
||| Splits a string into a list of newline separated strings.
|||
||| ```idris example
||| lines "\rA BC\nD\r\nE\n"
||| ```
export
lines : String -> List String
lines s = map pack (lines' (unpack s))
||| Joins the character lists by newlines into a single character list.
|||
||| ```idris example
||| unlines' [['l','i','n','e'], ['l','i','n','e','2'], ['l','n','3'], ['D']]
||| ```
unlines' : List (List Char) -> List Char
unlines' [] = []
unlines' (l::ls) = l ++ '\n' :: unlines' ls
||| Joins the strings by newlines into a single string.
|||
||| ```idris example
||| unlines ["line", "line2", "ln3", "D"]
||| ```
export
unlines : List String -> String
unlines = pack . unlines' . map unpack
export
ltrim : String -> String
ltrim xs = pack (ltrimChars (unpack xs))
where
ltrimChars : List Char -> List Char
ltrimChars [] = []
ltrimChars (x :: xs) = if isSpace x then ltrimChars xs else (x :: xs)
export
trim : String -> String
trim = ltrim . reverse . ltrim . reverse
||| Splits the string into a part before the predicate
||| returns False and the rest of the string.
|||
||| ```idris example
||| span (/= 'C') "ABCD"
||| ```
||| ```idris example
||| span (/= 'C') "EFGH"
||| ```
export
span : (Char -> Bool) -> String -> (String, String)
span p xs
= case span p (unpack xs) of
(x, y) => (pack x, pack y)
||| Splits the string into a part before the predicate
||| returns True and the rest of the string.
|||
||| ```idris example
||| break (== 'C') "ABCD"
||| ```
||| ```idris example
||| break (== 'C') "EFGH"
||| ```
public export
break : (Char -> Bool) -> String -> (String, String)
break p = span (not . p)
||| Splits the string into parts with the predicate
||| indicating separator characters.
|||
||| ```idris example
||| split (== '.') ".AB.C..D"
||| ```
public export
split : (Char -> Bool) -> String -> List String
split p xs = map pack (split p (unpack xs))
export
stringToNatOrZ : String -> Nat
stringToNatOrZ = fromInteger . prim__cast_StringInteger
export
toUpper : String -> String
toUpper str = pack (map toUpper (unpack str))
export
toLower : String -> String
toLower str = pack (map toLower (unpack str))
export
strIndex : String -> Int -> Char
strIndex = prim__strIndex
export
strTail : String -> String
strTail = prim__strTail
export
isPrefixOf : String -> String -> Bool
isPrefixOf a b = isPrefixOf (unpack a) (unpack b)
export
isSuffixOf : String -> String -> Bool
isSuffixOf a b = isSuffixOf (unpack a) (unpack b)
export
isInfixOf : String -> String -> Bool
isInfixOf a b = isInfixOf (unpack a) (unpack b)