{-# options_haddock prune #-} {- | Copyright: (c) 2016 Stephen Diehl (c) 2016-2018 Serokell (c) 2018-2021 Kowainik SPDX-License-Identifier: MIT Maintainer: Kowainik <xrom.xkov@gmail.com> Stability: Stable Portability: Portable Reexports functions to work with 'Data.Text.Text', 'ByteString' and 'ShortByteString' types. -} module Incipit.String.Reexport ( -- * String module Data.String , module Text.Read -- * Text , Text , lines , unlines , words , unwords , module Data.Text.Encoding , module Data.Text.Encoding.Error -- * ByteString , ByteString -- * ShortByteString , ShortByteString , toShort , fromShort ) where import Data.ByteString (ByteString) import Data.ByteString.Short (ShortByteString, fromShort, toShort) import Data.String (IsString (..), String) import qualified Data.Text as Text import Data.Text (Text) import Data.Text.Encoding (decodeUtf8', decodeUtf8With) import Data.Text.Encoding.Error (OnDecodeError, OnError, UnicodeException, lenientDecode, strictDecode) import GHC.TypeLits (ErrorMessage (..), Symbol, TypeError) import Text.Read (Read, readMaybe, reads) import Incipit.Base (Constraint, Type) -- $setup -- >>> import Relude -- | For tracking usage of Text instead of String type IsText (t :: Type) -- Textual type, e.g. Text, String (fun :: Symbol) -- Function name = (t ~ Text, CheckText t fun) type family CheckText (t :: Type) (fun :: Symbol) :: Constraint where CheckText Text _ = () CheckText String fun = TypeError ( 'Text "'" ':<>: 'Text fun ':<>: 'Text "' works with 'Text', not 'String'." ':$$: 'Text "Possible fixes:" ':$$: 'Text " 1. Make sure OverloadedStrings extension is enabled." ':$$: 'Text " 2. Apply 'toText' to a single value." ':$$: 'Text " 3. Apply 'map toText' to the list value." ) CheckText a fun = TypeError ( 'Text "'" ':<>: 'Text fun ':<>: 'Text "' works with 'Text'" ':$$: 'Text "But given: '" ':<>: 'ShowType a ':<>: 'Text "'" ) {- | 'lines' takes 'Data.Text.Text' and splits it into the list by lines. Actual type of this function is the following: @ lines :: 'Data.Text.Text' -> ['Data.Text.Text'] @ but it was given a more complex type to provide friendlier compile time errors. >>> lines "" [] >>> lines "one line" ["one line"] >>> lines "line 1\nline 2" ["line 1","line 2"] >>> lines ("string line" :: String) ... ... 'lines' works with 'Text', not 'String'. Possible fixes: 1. Make sure OverloadedStrings extension is enabled. 2. Apply 'toText' to a single value. 3. Apply 'map toText' to the list value. ... >>> lines True ... ... 'lines' works with 'Text' But given: 'Bool' ... -} lines :: IsText t "lines" => t -> [t] lines :: forall t. IsText t "lines" => t -> [t] lines = Text -> [Text] Text.lines {-# INLINE lines #-} {- | 'unlines' takes list of 'Data.Text.Text' values and joins them with line separator. Actual type of this function is the following: @ unlines :: ['Data.Text.Text'] -> 'Data.Text.Text' @ but it was given a more complex type to provide friendlier compile time errors. >>> unlines [] "" >>> unlines ["line 1"] "line 1\n" >>> unlines ["first line", "second line"] "first line\nsecond line\n" >>> unlines (["line 1", "line 2"] :: [String]) ... ... 'unlines' works with 'Text', not 'String'. Possible fixes: 1. Make sure OverloadedStrings extension is enabled. 2. Apply 'toText' to a single value. 3. Apply 'map toText' to the list value. ... >>> unlines [True, False] ... ... 'unlines' works with 'Text' But given: 'Bool' ... -} unlines :: IsText t "unlines" => [t] -> t unlines :: forall t. IsText t "unlines" => [t] -> t unlines = [Text] -> Text Text.unlines {-# INLINE unlines #-} {- | 'words' takes 'Data.Text.Text' and splits it into the list by words. Actual type of this function is the following: @ words :: 'Data.Text.Text' -> ['Data.Text.Text'] @ but it was given a more complex type to provide friendlier compile time errors. >>> words "" [] >>> words "one line" ["one","line"] >>> words " >_< " [">_<"] >>> words ("string words" :: String) ... ... 'words' works with 'Text', not 'String'. Possible fixes: 1. Make sure OverloadedStrings extension is enabled. 2. Apply 'toText' to a single value. 3. Apply 'map toText' to the list value. ... >>> words True ... ... 'words' works with 'Text' But given: 'Bool' ... -} words :: IsText t "words" => t -> [t] words :: forall t. IsText t "words" => t -> [t] words = Text -> [Text] Text.words {-# INLINE words #-} {- | 'unwords' takes list of 'Data.Text.Text' values and joins them with space character. Actual type of this function is the following: @ unwords :: ['Data.Text.Text'] -> 'Data.Text.Text' @ but it was given a more complex type to provide friendlier compile time errors. >>> unwords [] "" >>> unwords ["singleWord"] "singleWord" >>> unwords ["word", "another"] "word another" >>> unwords (["word", "another"] :: [String]) ... ... 'unwords' works with 'Text', not 'String'. Possible fixes: 1. Make sure OverloadedStrings extension is enabled. 2. Apply 'toText' to a single value. 3. Apply 'map toText' to the list value. ... >>> unwords [True, False] ... ... 'unwords' works with 'Text' But given: 'Bool' ... -} unwords :: IsText t "unwords" => [t] -> t unwords :: forall t. IsText t "unwords" => [t] -> t unwords = [Text] -> Text Text.unwords {-# INLINE unwords #-}