Skip to content

Commit dbcdacb

Browse files
authored
[ fix ] lines should not drop empty lines (#1372)
1 parent eb338fd commit dbcdacb

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,13 @@ Other minor additions
397397
id-⟶ : A ⟶ A
398398
```
399399

400-
* Added new function to `Data.String.Base`:
400+
* Added new function to `Data.List.Base`:
401+
```agda
402+
linesBy : Decidable P → List A → List (List A)
403+
```
404+
405+
* Added new functions to `Data.String.Base`:
401406
```agda
402-
lines : String → List String
407+
linesBy : Decidable P → String → List String
408+
lines : String → List String
403409
```

src/Data/List/Base.agda

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,23 @@ unsnoc as with initLast as
385385
------------------------------------------------------------------------
386386
-- Splitting a list
387387

388+
-- The predicate `P` represents the notion of newline character for the type `A`
389+
-- It is used to split the input list into a list of lines. Some lines may be
390+
-- empty if the input contains at least two consecutive newline characters.
391+
392+
linesBy : {P : Pred A p} Decidable P List A List (List A)
393+
linesBy {A = A} P? = go nothing where
394+
395+
go : Maybe (List A) List A List (List A)
396+
go acc [] = maybe′ ([_] ∘′ reverse) [] acc
397+
go acc (c ∷ cs) with does (P? c)
398+
... | true = reverse (Maybe.fromMaybe [] acc) ∷ go nothing cs
399+
... | false = go (just (c ∷ Maybe.fromMaybe [] acc)) cs
400+
401+
-- The predicate `P` represents the notion of space character for the type `A`.
402+
-- It is used to split the input list into a list of words. All the words are
403+
-- non empty and the output does not contain any space characters.
404+
388405
wordsBy : {P : Pred A p} Decidable P List A List (List A)
389406
wordsBy {A = A} P? = go [] where
390407

src/Data/String/Base.agda

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ open import Data.Bool.Base using (true; false)
1313
open import Data.Bool.Properties using (T?)
1414
open import Data.Nat.Base as ℕ using (ℕ; _∸_; ⌊_/2⌋; ⌈_/2⌉)
1515
import Data.Nat.Properties as ℕₚ
16-
open import Data.List.Base as List using (List; [_])
16+
open import Data.List.Base as List using (List; _∷_; []; [_])
1717
open import Data.List.NonEmpty as NE using (List⁺)
1818
open import Data.List.Extrema ℕₚ.≤-totalOrder
1919
open import Data.List.Relation.Binary.Pointwise using (Pointwise)
@@ -23,6 +23,7 @@ open import Data.Char.Base as Char using (Char)
2323
import Data.Char.Properties as Char using (_≟_)
2424
open import Function
2525
open import Relation.Binary using (Rel)
26+
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
2627
open import Relation.Nullary using (does)
2728
open import Relation.Unary using (Pred; Decidable)
2829

@@ -95,11 +96,22 @@ wordsBy P? = List.map fromList ∘ List.wordsBy P? ∘ toList
9596
words : String List String
9697
words = wordsBy (T? ∘ Char.isSpace)
9798

99+
-- `words` ignores contiguous whitespace
100+
_ : words " abc b ""abc""b" ∷ []
101+
_ = refl
102+
98103
unwords : List String String
99104
unwords = intersperse " "
100105

106+
linesBy : {p} {P : Pred Char p} Decidable P String List String
107+
linesBy P? = List.map fromList ∘ List.linesBy P? ∘ toList
108+
101109
lines : String List String
102-
lines = wordsBy ('\n' Char.≟_)
110+
lines = linesBy ('\n' Char.≟_)
111+
112+
-- `lines` preserves empty lines
113+
_ : lines "\nabc\n\nb\n\n\n""""abc""""b""""" ∷ []
114+
_ = refl
103115

104116
unlines : List String String
105117
unlines = intersperse "\n"

0 commit comments

Comments
 (0)