on master help sign in
Implement and test lazy init
95b326bBryan O'Sullivan
Data/Text/Lazy.hs+17−1
@@ -47,7 +47,7 @@ module Data.Text.Lazy
47 , head
47 , head
48 , last
48 , last
49 , tail
49 , tail
50− -- , init
50+ , init
51 -- , null
51 -- , null
52 -- , length
52 -- , length
53
53
@@ -251,6 +251,8 @@ head :: Text -> Char
251head t = S.head (stream t)
251head t = S.head (stream t)
252{-# INLINE head #-}
252{-# INLINE head #-}
253
253
254+-- | /O(1)/ Returns all characters after the head of a 'Text', which
255+-- must be non-empty. Subject to array fusion.
254tail :: Text -> Text
256tail :: Text -> Text
255tail (Chunk t ts) = chunk (T.tail t) ts
257tail (Chunk t ts) = chunk (T.tail t) ts
256tail Empty = emptyError "tail"
258tail Empty = emptyError "tail"
@@ -263,6 +265,20 @@ tail Empty = emptyError "tail"
263 unstream (S.tail (stream t)) = tail t
265 unstream (S.tail (stream t)) = tail t
264 #-}
266 #-}
265
267
268+init :: Text -> Text
269+init (Chunk t0 ts0) = go t0 ts0
270+ where go t (Chunk t' ts) = Chunk t (go t' ts)
271+ go t Empty = chunk (T.init t) Empty
272+init Empty = emptyError "init"
273+{-# INLINE [1] init #-}
274+
275+{-# RULES
276+"LAZY TEXT init -> fused" [~1] forall t.
277+ init t = unstream (S.init (stream t))
278+"LAZY TEXT init -> unfused" [1] forall t.
279+ unstream (S.init (stream t)) = init t
280+ #-}
281+
266-- | /O(1)/ Returns the last character of a 'Text', which must be
282-- | /O(1)/ Returns the last character of a 'Text', which must be
267-- non-empty. Subject to array fusion.
283-- non-empty. Subject to array fusion.
268last :: Text -> Char
284last :: Text -> Char
tests/Properties.hs+4−2
@@ -130,8 +130,9 @@ prop_TL_last = last `eqEP` TL.last
130prop_S_tail = tail `eqEP` (unpackT . S.tail)
130prop_S_tail = tail `eqEP` (unpackT . S.tail)
131prop_T_tail = tail `eqEP` (unpackT . T.tail)
131prop_T_tail = tail `eqEP` (unpackT . T.tail)
132prop_TL_tail = tail `eqEP` (unpackT . TL.tail)
132prop_TL_tail = tail `eqEP` (unpackT . TL.tail)
133+prop_S_init = init `eqEP` (unpackT . S.init)
133prop_T_init = init `eqEP` (unpackT . T.init)
134prop_T_init = init `eqEP` (unpackT . T.init)
134−prop_T_initS = init `eqEP` (unpackT . S.unstream . S.init . S.stream)
135+prop_TL_init = init `eqEP` (unpackT . TL.init)
135prop_T_null = null `eqP` T.null
136prop_T_null = null `eqP` T.null
136prop_T_length = length `eqP` T.length
137prop_T_length = length `eqP` T.length
137prop_T_map f = map f `eqP` (unpackT . T.map f)
138prop_T_map f = map f `eqP` (unpackT . T.map f)
@@ -308,8 +309,9 @@ tests = [
308 ("prop_S_tail", mytest prop_S_tail),
309 ("prop_S_tail", mytest prop_S_tail),
309 ("prop_T_tail", mytest prop_T_tail),
310 ("prop_T_tail", mytest prop_T_tail),
310 ("prop_TL_tail", mytest prop_TL_tail),
311 ("prop_TL_tail", mytest prop_TL_tail),
312+ ("prop_S_init", mytest prop_S_init),
311 ("prop_T_init", mytest prop_T_init),
313 ("prop_T_init", mytest prop_T_init),
312− ("prop_T_initS", mytest prop_T_initS),
314+ ("prop_TL_init", mytest prop_TL_init),
313 ("prop_T_null", mytest prop_T_null),
315 ("prop_T_null", mytest prop_T_null),
314 ("prop_T_length", mytest prop_T_length),
316 ("prop_T_length", mytest prop_T_length),
315
317