listFloating :: [Double] = [0.0, 1.0, -1.0, 0.5, -0.5, 2.0, Infinity, -Infinity, -2.0, 0.333, ...]This follow the same Calkin-Wilf sequence of listFractional but positive and negative infinities are artificially included after two. NaN and -0 are excluded from this enumeration.
listFractional :: [[Rational]] = [0 % 1, 1 % 1, (-1) % 1, 1 % 2, (-1) % 2, 2 % 1, (-2) % 1, 1 % 3, ...]All rationals are included without repetition in their most simple form. This is the Calkin-Wilf sequence computed with the help of the fusc function (EWD 570). This also works for unsigned types that wrap around zero, yielding:
listFractional :: [Ratio Word] = [0 % 1, 1 % 1, 1 % 2, 2 % 1, 1 % 3, 3 % 2, 2 % 3, 3 % 1, 1 % 4, ...]
listIntegral = [0, 1, -1, 2, -2, 3, -3, 4, -4, ...]For types without negative values, like Word, the list starts with 0 followed by positives of increasing magnitude.
listIntegral = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...]This function will not work for types that throw errors when the result of an arithmetic operation is negative such as Natural. For these, use [0..] as the list implementation.
listsOf [[]] = [[[]]]
listsOf [[x]] = [ [[]] , [[x]] , [[x,x]] , [[x,x,x]] , ... ]
listsOf [[x],[y]] = [ [[]] , [[x]] , [[x,x],[y]] , [[x,x,x],[x,y],[y,x]] , ... ]
listsOfLength 3 [[0],[1],[2],[3],[4]...] = [ [[0,0,0]] , [[0,0,1],[0,1,0],[1,0,0]] , [[0,0,2],[0,1,1],[0,2,0],[1,0,1],[1,1,0],[2,0,0]] , ... ]
tiers = cons<N> ConstructorA \/ cons<N> ConstructorB \/ ... \/ cons<N> ConstructorZwhere N is the number of arguments of each constructor A...Z. Here is a datatype with 4 constructors and its listable instance:
data MyType = MyConsA | MyConsB Int | MyConsC Int Char | MyConsD String instance Listable MyType where tiers = cons0 MyConsA \/ cons1 MyConsB \/ cons2 MyConsC \/ cons1 MyConsDThe instance for Hutton's Razor is given by:
data Expr = Val Int | Add Expr Expr instance Listable Expr where tiers = cons1 Val \/ cons2 AddInstances can be alternatively defined by list. In this case, each sub-list in tiers is a singleton list (each succeeding element of list has +1 size). The function deriveListable from Test.LeanCheck.Derive can automatically derive instances of this typeclass. A Listable instance for functions is also available but is not exported by default. Import Test.LeanCheck.Function if you need to test higher-order properties.
data Stack a = Stack a (Stack a) | EmptyWriting
deriveListable ''Stackwill automatically derive the following Listable instance:
instance Listable a => Listable (Stack a) where tiers = cons2 Stack \/ cons0 EmptyWarning: if the values in your type need to follow a data invariant, the derived instance won't respect it. Use this only on "free" datatypes. Needs the TemplateHaskell extension.
data Position = CEO | Manager | Programmer data Person = Person { name :: String , age :: Int , position :: Position } data Company = Company { name :: String , employees :: [Person] }Writing
deriveListableCascading ''Companywill automatically derive the following three Listable instances:
instance Listable Position where tiers = cons0 CEO \/ cons0 Manager \/ cons0 Programmer instance Listable Person where tiers = cons3 Person instance Listable Company where tiers = cons2 Company
noDupListsOf [[0],[1],[2],...] == [ [[]] , [[0]] , [[1]] , [[0,1],[1,0],[2]] , [[0,2],[2,0],[3]] , ... ]
> list :: [Bool] [False,True] > funToList not [True,False]
> list :: [(Bool,Bool)] [(False,False),(False,True),(True,False),(True,True)] > funToList $ uncurry (&&) [False,False,False,True]This function may return an infinite list, use take as required.
> take 10 $ list :: [Int] [0,1,-1,2,-2,3,-3,4,-4,5] > take 10 $ funToList (+1) :: [Int] [1,2,0,3,-1,4,-2,5,-3,6]
> take 6 $ funToListEither $ head :: [Either String Int] [Left "Prelude.head: empty list",Right 0,Right 0,Right 1,Right 0,Right 0]This uses errorToLeft and consequently unsafePerformIO.
> take 6 $ funToListMaybe $ head :: [Maybe Int] [Nothing,Just 0,Just 0,Just 1,Just 0,Just 0]This uses errorToNothing and consequently unsafePerformIO.
instance Listable MyType where list = genericListConsider using genericTiers instead of this (unless you know what you're doing).