From f33b6fb3f5a5caf0d06148131fff0a22f8a18a39 Mon Sep 17 00:00:00 2001 From: "Michal J. Gajda" Date: Sun, 19 Apr 2026 21:12:34 +0200 Subject: [PATCH] Add containers group for redundant toList rewrites (fixes #1570) New hint group `containers` with rewrites that bypass the intermediate list produced by `Data.IntMap.toList`, `Data.IntSet.toList`, `Data.Map.toList` and `Data.Set.toList` in favour of the container's own fold and predicate primitives. Adds a matching `package: containers` declaration so the group's `imports:` can reference it. All rewrite targets are fully qualified (`Data.Map.null`, `Data.IntSet.member`, etc.), so the group is safe to enable by default: it only fires when the qualified containers API is already in use. --- data/hlint.yaml | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/data/hlint.yaml b/data/hlint.yaml index f007f2b2..dd750ca3 100644 --- a/data/hlint.yaml +++ b/data/hlint.yaml @@ -65,6 +65,18 @@ modules: - import CodeWorld +- package: + name: containers + modules: + - import Data.IntMap + - import Data.IntMap.Lazy + - import Data.IntMap.Strict + - import Data.IntSet + - import Data.Map + - import Data.Map.Lazy + - import Data.Map.Strict + - import Data.Set + - group: name: default enabled: true @@ -1133,6 +1145,43 @@ rules: - hint: {lhs: "TH.varE 'a", rhs: "[|a|]", name: Use TH quotation brackets} +- group: + name: containers + enabled: true + imports: + - package base + - package containers + rules: + - warn: {lhs: foldMap f (Data.IntMap.toList x), rhs: Data.IntMap.foldMapWithKey (curry f) x} + - warn: {lhs: foldr f z (Data.IntMap.toList x), rhs: Data.IntMap.foldrWithKey (curry f) z x} + - warn: {lhs: foldr' f z (Data.IntMap.toList x), rhs: Data.IntMap.foldrWithKey' (curry f) z x} + - warn: {lhs: foldl f z (Data.IntMap.toList x), rhs: Data.IntMap.foldlWithKey (curry . f) z x} + - warn: {lhs: foldl' f z (Data.IntMap.toList x), rhs: Data.IntMap.foldlWithKey' (curry . f) z x} + - warn: {lhs: null (Data.IntMap.toList x), rhs: Data.IntMap.null x} + - warn: {lhs: length (Data.IntMap.toList x), rhs: Data.IntMap.size x} + + - warn: {lhs: foldr f z (Data.IntSet.toList x), rhs: Data.IntSet.foldr f z x} + - warn: {lhs: foldr' f z (Data.IntSet.toList x), rhs: Data.IntSet.foldr' f z x} + - warn: {lhs: foldl f z (Data.IntSet.toList x), rhs: Data.IntSet.foldl f z x} + - warn: {lhs: foldl' f z (Data.IntSet.toList x), rhs: Data.IntSet.foldl' f z x} + - warn: {lhs: null (Data.IntSet.toList x), rhs: Data.IntSet.null x} + - warn: {lhs: length (Data.IntSet.toList x), rhs: Data.IntSet.size x} + - warn: {lhs: elem y (Data.IntSet.toList x), rhs: Data.IntSet.member y x} + - warn: {lhs: notElem y (Data.IntSet.toList x), rhs: Data.IntSet.notMember y x} + + - warn: {lhs: foldMap f (Data.Map.toList x), rhs: Data.Map.foldMapWithKey (curry f) x} + - warn: {lhs: foldr f z (Data.Map.toList x), rhs: Data.Map.foldrWithKey (curry f) z x} + - warn: {lhs: foldr' f z (Data.Map.toList x), rhs: Data.Map.foldrWithKey' (curry f) z x} + - warn: {lhs: foldl f z (Data.Map.toList x), rhs: Data.Map.foldlWithKey (curry . f) z x} + - warn: {lhs: foldl' f z (Data.Map.toList x), rhs: Data.Map.foldlWithKey' (curry . f) z x} + - warn: {lhs: null (Data.Map.toList x), rhs: Data.Map.null x} + - warn: {lhs: length (Data.Map.toList x), rhs: Data.Map.size x} + + - warn: {lhs: null (Data.Set.toList x), rhs: Data.Set.null x} + - warn: {lhs: length (Data.Set.toList x), rhs: Data.Set.size x} + - warn: {lhs: elem y (Data.Set.toList x), rhs: Data.Set.member y x} + - warn: {lhs: notElem y (Data.Set.toList x), rhs: Data.Set.notMember y x} + - group: name: attoparsec enabled: true