Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions data/hlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,35 @@
- warn: {lhs: foldr' f c (reverse x), rhs: foldl' (flip f) c x, name: Use left fold instead of right fold}
- warn: {lhs: foldl' f c (reverse x), rhs: foldr (flip f) c x, note: IncreasesLaziness, name: Use right fold instead of left fold}

- group:
name: performance
enabled: false
rules:

# Text / ByteString strict left folds. The lazy `foldl` over these
# bulk-data types builds a thunk chain proportional to the element
# count, which blows the stack on realistic inputs. `foldl'` is a
# drop-in, same-module replacement whenever the accumulator is
# strict-amenable (which it almost always is for numeric counters,
# Builders, strict Maps, etc.). Match fully-qualified names only so
# the rule does not fire on the unrelated Foldable-polymorphic
# `foldl` from Prelude/Data.Foldable.
- warn: {lhs: Data.Text.foldl f z t, rhs: Data.Text.foldl' f z t, name: "Use foldl'"}
- warn: {lhs: Data.Text.Lazy.foldl f z t, rhs: Data.Text.Lazy.foldl' f z t, name: "Use foldl'"}
- warn: {lhs: Data.ByteString.foldl f z b, rhs: Data.ByteString.foldl' f z b, name: "Use foldl'"}
- warn: {lhs: Data.ByteString.Lazy.foldl f z b, rhs: Data.ByteString.Lazy.foldl' f z b, name: "Use foldl'"}
- warn: {lhs: Data.ByteString.Char8.foldl f z b, rhs: Data.ByteString.Char8.foldl' f z b, name: "Use foldl'"}
- warn: {lhs: Data.ByteString.Lazy.Char8.foldl f z b, rhs: Data.ByteString.Lazy.Char8.foldl' f z b, name: "Use foldl'"}

# Text concat-of-map fuses into concatMap, avoiding the intermediate
# [Text] spine and its associated allocation. Semantics-preserving:
# `Data.Text.concatMap f = Data.Text.concat . map f` by construction.
# Not applied to ByteString: `Data.ByteString.concatMap` has type
# (Word8 -> ByteString) -> ByteString -> ByteString, so it is NOT
# the fusion of `concat . map` over `[ByteString]`.
- warn: {lhs: Data.Text.concat (map f xs), rhs: Data.Text.concatMap f xs, name: "Use Data.Text.concatMap"}
- warn: {lhs: Data.Text.Lazy.concat (map f xs), rhs: Data.Text.Lazy.concatMap f xs, name: "Use Data.Text.Lazy.concatMap"}

- group:
# used for tests, enabled when testing this file
name: testing
Expand Down
68 changes: 68 additions & 0 deletions tests/flag-with-group-performance-text-bs.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---------------------------------------------------------------------
FILE tests/flag-with-group-performance-text-bs.hs
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy.Char8 as BLC
ft f z t = print (T.foldl f z t)
ftl f z t = print (TL.foldl f z t)
fbs f z b = print (BS.foldl f z b)
fbl f z b = print (BL.foldl f z b)
fbsc f z b = print (BSC.foldl f z b)
fblc f z b = print (BLC.foldl f z b)
ct f xs = print (T.concat (map f xs))
ctl f xs = print (TL.concat (map f xs))
RUN "--with-group=performance" tests/flag-with-group-performance-text-bs.hs
OUTPUT
tests/flag-with-group-performance-text-bs.hs:7:19-31: Warning: Use foldl'
Found:
T.foldl f z t
Perhaps:
T.foldl' f z t

tests/flag-with-group-performance-text-bs.hs:8:20-33: Warning: Use foldl'
Found:
TL.foldl f z t
Perhaps:
TL.foldl' f z t

tests/flag-with-group-performance-text-bs.hs:9:20-33: Warning: Use foldl'
Found:
BS.foldl f z b
Perhaps:
BS.foldl' f z b

tests/flag-with-group-performance-text-bs.hs:10:20-33: Warning: Use foldl'
Found:
BL.foldl f z b
Perhaps:
BL.foldl' f z b

tests/flag-with-group-performance-text-bs.hs:11:21-35: Warning: Use foldl'
Found:
BSC.foldl f z b
Perhaps:
BSC.foldl' f z b

tests/flag-with-group-performance-text-bs.hs:12:21-35: Warning: Use foldl'
Found:
BLC.foldl f z b
Perhaps:
BLC.foldl' f z b

tests/flag-with-group-performance-text-bs.hs:13:18-36: Warning: Use Data.Text.concatMap
Found:
T.concat (map f xs)
Perhaps:
T.concatMap f xs

tests/flag-with-group-performance-text-bs.hs:14:19-38: Warning: Use Data.Text.Lazy.concatMap
Found:
TL.concat (map f xs)
Perhaps:
TL.concatMap f xs

8 hints