We do not have a test to confirm that the initial selection for a
list is always 'Just 0' (or 'Nothing' when the list is empty). Add
a test for this contract.
List / GenericList derives Foldable, which means that in many cases
where 'length (l ^. listElementsL)' was written, we can instead
write 'length l'. Likewise for 'null'. Avoid these unnecessary
applications.
A common use case is to seek to the next occurrence in the list of
an element matching some predicate (e.g. next unread email). Add
the 'listFindBy' function to satisfy this use case.
'listFindBy' is lazy. Also redefine 'listMoveToElement' in terms of
'listFindBy', making it lazy. This changes the constraints from
(Traversable t) to (Foldable t, Splittable t), which is reasonable.
'listMoveBy' was evaluating the whole container, making it (and the
many functions that use it) unusable for applications needing lazy
loading. Fix the function and add a regression test.
Add an instance of Splittable for Data.Sequence.Seq, and QuickCheck
properties for it.
Add lower bound containers >= 0.5.7, being the version at which the
Semigroup instance was introduced.
Introduce 'GenericList' which abstracts list behaviour over the
container type. This allows the use of types other than Vector, if
it would suit a particular application (e.g. lazy loading of list
contents).
'List' is retained as a type synonym for backwards compatibility.
For a container type to be usable with 'List', it must have
instances of 'Traversable' and a new type class 'Splittable' which
allows splitting the container at a given index.
Some operations impose additional constraints on the container type:
- listInsert: 'Applicative' and 'Semigroup'
- listRemove: 'Semigroup'
- listClear: 'Monoid'
Fixes: https://github.com/jtdaugherty/brick/issues/201
Add QuickCheck properties for the behaviour described in the
'listMoveBy' haddock, particularly for when there is no current
selection. Then fix 'listMoveBy' to make the tests pass.
Add some property tests for List behaviour. Among other things,
check that the "selected element" bookkeeping maintains a valid
selection at all times (as long as you're using the provided
functions and not manipulating the underlying Vector directly).
The current 'main' has type 'IO Bool' but a return value of 'False'
does not cause the program to exit with nonzero status. Witnessed
by the following:
ftweedal% cat foo.hs
main :: IO Bool
main = putStrLn "goodbye world" *> pure False
ftweedal% runhaskell foo.hs
goodbye world
ftweedal% echo $?
0
This causes the cabal test suite to pass, even when there are
errors. Unless you inspect the QuickCheck output carefully, you
might not notice that a test is failing. Update 'main' to ensure
that we exit nonzero when quickCheckAll returns 'False'.