summaryrefslogtreecommitdiffstats
path: root/src/Data/WText.hs
blob: 9624b374d95ff0201405dca96f22cc808f6b2963 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}

module Data.WText where

import Prelude hiding (break, drop, map, splitAt, take)
import Prelude qualified

import Data.Coerce (coerce)
import Data.String (IsString(..))
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.WCWidth qualified as WT

import Data.Sequences
import Data.MonoTraversable


newtype WText = WText { unWText :: Text }
  deriving (Eq, Ord, Show, IsString, Semigroup, Monoid)
  deriving (MonoFoldable, MonoFunctor) via Text


type instance Element WText = Char

instance MonoTraversable WText where
  otraverse f (WText t) = WText <$> otraverse f t

instance MonoPointed WText where
  opoint c = WText (T.singleton c)

instance GrowingAppend WText
--gappend (WText a) (WText b) = WText (a <> b)

instance IsSequence WText where
  fromList    = WText . T.pack
  --singleton   = WText . T.singleton

  --index (WText t)       = T.index t
  lengthIndex (WText t) = T.length t

  take n (WText t)    = WText (T.take n t)
  drop n (WText t)    = WText (T.drop n t)
  splitAt n (WText t) =
    let (a,b) = T.splitAt n t
    in (WText a, WText b)

instance SemiSequence WText where
  type Index WText = Int

  intersperse c (WText t) = WText (T.intersperse c t)

  reverse (WText t) = WText (T.reverse t)

  cons c (WText t) = WText (T.cons c t)
  snoc (WText t) c = WText (T.snoc t c)

  find p (WText t) = find p t

  sortBy cmp (WText t) =
    WText (T.pack (sortBy cmp (T.unpack t)))

instance Textual WText where
  words (WText t)   = Prelude.map WText (T.words t)
  unwords ws        = WText (T.unwords (ofoldMap (\(WText t) -> [t]) ws))

  lines (WText t)   = Prelude.map WText (T.lines t)
  unlines ws        = WText (T.unlines (ofoldMap (\(WText t) -> [t]) ws))

  toLower (WText t)    = WText (T.toLower t)
  toUpper (WText t)    = WText (T.toUpper t)
  toCaseFold (WText t) = WText (T.toCaseFold t)


--------------------------------------------------------------------------------
-- low-level
--------------------------------------------------------------------------------

split :: (Char -> Bool) -> WText -> [WText]
split = coerce WT.wsplit

splitAt :: Int -> WText -> (WText, WText)
splitAt = coerce WT.wsplitAt

take :: Int -> WText -> WText
take = coerce WT.wtake

drop :: Int -> WText -> WText
drop = coerce WT.wdrop

length :: WText -> Int
length = coerce WT.wlength


--------------------------------------------------------------------------------
-- coercible
--------------------------------------------------------------------------------

null :: WText -> Bool
null = coerce T.null 

filter :: (Char -> Bool) -> WText -> WText
filter = coerce T.filter

map :: (Char -> Char) -> WText -> WText
map = coerce T.map

reverse
  , strip
  , toUpper
  , toLower
  :: WText -> WText
reverse = coerce T.reverse
strip = coerce T.strip
toUpper = coerce T.toUpper
toLower = coerce T.toLower

stripPrefix, stripSuffix :: WText -> WText -> Maybe WText
stripPrefix = coerce T.stripPrefix
stripSuffix = coerce T.stripSuffix

replace :: WText -> WText -> WText -> WText
replace = coerce T.replace

intercalate :: WText -> [WText] -> WText
intercalate = coerce T.intercalate

isPrefixOf
  , isSuffixOf
  , isInfixOf
  :: WText -> WText -> Bool
isPrefixOf = coerce T.isPrefixOf
isSuffixOf = coerce T.isSuffixOf
isInfixOf = coerce T.isInfixOf