{-|

Module      : Trim
Description : An inefficient trim white space from front of string.
Copyright   : © Frank Jung, 2020
License     : GPL-3

An inefficient alternative to 'dropWhile'.

= Examples

>>> trim " hello world "
"hello world"

>>> dropWhile' isSpace " hello world "
"hello word "

>>> dropWhileEnd' isSpace " hello world "
" hello word"

-}

module Trim (dropWhile', dropWhileEnd', trimStart, trimEnd, trim) where

import           Data.Char (isSpace)
import           Data.List (foldl')

-- | Trim white space from start of string.
trimStart :: String -> String
trimStart :: String -> String
trimStart = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile' Char -> Bool
isSpace

-- | Trim white space from end of string.
trimEnd :: String -> String
trimEnd :: String -> String
trimEnd = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd' Char -> Bool
isSpace

-- | Trim white space from start and end of string.
trim :: String -> String
trim :: String -> String
trim = String -> String
trimStart (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
trimEnd

-- | Drop from beginning of list while predicate is true.
dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' :: forall a. (a -> Bool) -> [a] -> [a]
dropWhile' a -> Bool
p = [a] -> [a]
forall a. [a] -> [a]
reverse ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> a -> [a]) -> [a] -> [a] -> [a]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\[a]
z a
x -> if [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
z Bool -> Bool -> Bool
&& a -> Bool
p a
x then [a]
z else a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
z) []

-- | Drop from end of list while predicate is true.
dropWhileEnd' :: (a -> Bool) -> [a] -> [a]
dropWhileEnd' :: forall a. (a -> Bool) -> [a] -> [a]
dropWhileEnd' a -> Bool
p = (a -> [a] -> [a]) -> [a] -> [a] -> [a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a
x [a]
z -> if a -> Bool
p a
x Bool -> Bool -> Bool
&& [a] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
z then [] else a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
z) []