packages feed

list-extras 0.4.1.4 → 0.4.1.6

raw patch · 14 files changed

+642/−623 lines, 14 filessetup-changednew-uploader

Files

CHANGELOG view
@@ -1,3 +1,8 @@+0.4.1.6 (2021-10-17):+    - Updating maintainer's email, url, etc+    - Set up GithubActions for CI.+0.4.1.4 (2015-05-30):+    - Moved VERSION to CHANGELOG 0.4.1 (2012-09-26):     - Prelude.Listless: Guarded re-export of Prelude.catch with CPP 0.4.0.1 (2010-05-31):
− Data/List/Extras.hs
@@ -1,37 +0,0 @@-{-# OPTIONS_GHC -Wall -fwarn-tabs #-}--------------------------------------------------------------------                                                  ~ 2010.04.05--- |--- Module      :  Data.List.Extras--- Copyright   :  Copyright (c) 2007--2015 wren gayle romano--- License     :  BSD3--- Maintainer  :  wren@community.haskell.org--- Stability   :  stable--- Portability :  Haskell98------ This module provides a single header for all @Data.List.Extras.*@--- modules and provides a small number of other utility functions.-------------------------------------------------------------------module Data.List.Extras-    (-      list-    , module Data.List.Extras.LazyLength-    , module Data.List.Extras.Pair-    , module Data.List.Extras.Argmax-    ) where--import Data.List.Extras.LazyLength-import Data.List.Extras.Pair-import Data.List.Extras.Argmax---- | Pattern matching for lists, as a first-class function. (Could--- also be considered as a non-recursive 'foldr'.) If the list--- argument is @[]@ then the default argument is returned; otherwise--- the function is called with the head and tail of the list.-list :: (a -> [a] -> b) -> b -> [a] -> b-list _ z []     = z-list f _ (x:xs) = f x xs------------------------------------------------------------------------------------------------------------------------------ fin.
− Data/List/Extras/Argmax.hs
@@ -1,204 +0,0 @@-{-# OPTIONS_GHC -Wall -fwarn-tabs #-}--------------------------------------------------------------------                                                  ~ 2010.10.15--- |--- Module      :  Data.List.Extras.ArgMax--- Copyright   :  Copyright (c) 2007--2015 wren gayle romano--- License     :  BSD3--- Maintainer  :  wren@community.haskell.org--- Stability   :  experimental--- Portability :  Haskell98------ This module provides variants of the 'maximum' and 'minimum'--- functions which return the elements for which some function is--- maximized or minimized.-------------------------------------------------------------------module Data.List.Extras.Argmax-    (-    -- * Utility functions-      catchNull-    -    -- * Generic versions-    , argmaxBy, argmaxesBy, argmaxWithMaxBy, argmaxesWithMaxBy-    -    -- * Maximum variations-    , argmax,   argmaxes,   argmaxWithMax,   argmaxesWithMax-    -    -- * Minimum variations-    , argmin,   argmins,    argminWithMin,   argminsWithMin-    -    {- TODO: CPS and monadic variants; argmax2, argmax3,... -}-    {- TODO: make sure argmax et al are "good consumers" for fusion -}-    ) where--- argmaxM       :: (Monad m, Ord b) => (a -> m b) -> [a] -> m (Maybe a)--import Data.List (foldl')--------------------------------------------------------------------------------------------------------------------------------------- | Apply a list function safely, i.e. when the list is non-empty.--- All other functions will throw errors on empty lists, so use--- this to make your own safe variations.-catchNull :: ([a] -> b) -> ([a] -> Maybe b)-{-# INLINE catchNull #-}--- We use the explicit lambda in order to improve inlining in ghc-7.-catchNull f = \xs ->-    case xs of-    []  -> Nothing-    _:_ -> Just (f xs)----- | Minimize the number of string literals-emptyListError :: String -> a-{-# NOINLINE emptyListError #-}-emptyListError fun =-    error $ "Data.List.Extras.Argmax."++fun++": empty list"----- | Apply a list function unsafely. For internal use.-throwNull :: String -> (a -> [a] -> b) -> ([a] -> b)-{-# INLINE throwNull #-}--- We use the explicit lambda in order to improve inlining in ghc-7.-throwNull fun f = \xs ->-    case xs of-    []    -> emptyListError fun-    x:xs' -> f x xs'-------------------------------------------------------------------------------------------------------------------------------------- | Tail-recursive driver-_argmaxWithMaxBy :: (b -> b -> Bool) -> (a -> b) -> a -> [a] -> (a,b)-{-# INLINE _argmaxWithMaxBy #-}--- We use the explicit lambda in order to improve inlining in ghc-7.-_argmaxWithMaxBy isBetterThan f =-    \x xs -> foldl' cmp (x, f x) xs-    where-    cmp bfb@(_,fb) a =-        let  fa = f a in-        if   fa `isBetterThan` fb-        then (a,fa)-        else bfb----- | Tail-recursive driver-_argmaxesWithMaxBy :: (b -> b -> Ordering) -> (a -> b) -> a -> [a] -> ([a],b)-{-# INLINE _argmaxesWithMaxBy #-}--- We use the explicit lambda in order to improve inlining in ghc-7.-_argmaxesWithMaxBy isBetterEqualThan f =-    \x xs -> foldl' cmp ([x], f x) xs-    where-    cmp bsfb@(bs,fb) a =-        let  fa = f a in-        case isBetterEqualThan fa fb of-             GT -> ([a],  fa)-             EQ -> (a:bs, fb)-             _  -> bsfb---_argmaxBy :: (b -> b -> Bool) -> (a -> b) -> a -> [a] -> a-{-# INLINE _argmaxBy #-}--- We use the point-free style in order to improve inlining in ghc-7.-_argmaxBy k f = (fst .) . _argmaxWithMaxBy k f---_argmaxesBy :: (b -> b -> Ordering) -> (a -> b) -> a -> [a] -> [a]-{-# INLINE _argmaxesBy #-}--- We use the point-free style in order to improve inlining in ghc-7.-_argmaxesBy k f = (fst .) . _argmaxesWithMaxBy k f-------------------------------------------------------------------------------------------------------------------------------------bool    :: (a -> a -> Ordering) -> (a -> a -> Bool)-bool ord = \a b -> ord a b == GT----- | Return an element of the list which maximizes the function--- according to a user-defined ordering.-argmaxBy        :: (b -> b -> Ordering) -> (a -> b) -> [a] -> a-argmaxBy   ord f = throwNull "argmaxBy"-                 $ _argmaxBy (bool ord) f----- | Return all elements of the list which maximize the function--- according to a user-defined ordering.-argmaxesBy      :: (b -> b -> Ordering) -> (a -> b) -> [a] -> [a]-argmaxesBy ord f = throwNull "argmaxesBy"-                 $ _argmaxesBy ord f----- | Return an element of the list which maximizes the function--- according to a user-defined ordering, and return the value of--- the function at that element as well.-argmaxWithMaxBy        :: (b -> b -> Ordering) -> (a -> b) -> [a] -> (a, b)-argmaxWithMaxBy   ord f = throwNull "argmaxWithMaxBy" -                        $ _argmaxWithMaxBy (bool ord) f----- | Return all elements of the list which maximize the function--- according to a user-defined ordering, and return the value of--- the function at those elements as well.-argmaxesWithMaxBy      :: (b -> b -> Ordering) -> (a -> b) -> [a] -> ([a], b)-argmaxesWithMaxBy ord f = throwNull "argmaxesWithMaxBy"-                        $ _argmaxesWithMaxBy ord f--------------------------------------------------------------------- SPECIALIZE on b \in {Int,Integer,Float,Double} for the four--- functions below nearly doubles the library size (about +21kB).--- For a basic utility library that's a bit excessive, though if--- we break the argmax stuff out from list-extras then we might go--- through with it for performance sake.---- | Return an element of the list which maximizes the function.-argmax    :: (Ord b) => (a -> b) -> [a] -> a-argmax   f = throwNull "argmax"-           $ _argmaxBy (>) f---- | Return all elements of the list which maximize the function.-argmaxes  :: (Ord b) => (a -> b) -> [a] -> [a]-argmaxes f = throwNull "argmaxes"-           $ _argmaxesBy compare f----- | Return an element of the list which maximizes the function,--- and return the value of the function at that element as well.-argmaxWithMax    :: (Ord b) => (a -> b) -> [a] -> (a, b)-argmaxWithMax   f = throwNull "argmaxWithMax" -                  $ _argmaxWithMaxBy (>) f----- | Return all elements of the list which maximize the function,--- and return the value of the function at those elements as well.-argmaxesWithMax  :: (Ord b) => (a -> b) -> [a] -> ([a], b)-argmaxesWithMax f = throwNull "argmaxesWithMax"-                  $ _argmaxesWithMaxBy compare f---------------------------------------------------------------------- | Return an element of the list which minimizes the function.-argmin   :: (Ord b) => (a -> b) -> [a] -> a-argmin  f = throwNull "argmax"-          $ _argmaxBy (<) f---- | Return all elements of the list which minimize the function.-argmins  :: (Ord b) => (a -> b) -> [a] -> [a]-argmins f = throwNull "argmins"-          $ _argmaxesBy (flip compare) f----- | Return an element of the list which minimizes the function,--- and return the value of the function at that element as well.-argminWithMin   :: (Ord b) => (a -> b) -> [a] -> (a, b)-argminWithMin  f = throwNull "argminWithMin"-                 $ _argmaxWithMaxBy (<) f---- | Return all elements of the list which minimize the function,--- and return the value of the function at those elements as well.-argminsWithMin  :: (Ord b) => (a -> b) -> [a] -> ([a], b)-argminsWithMin f = throwNull "argminsWithMin"-                 $ _argmaxesWithMaxBy (flip compare) f------------------------------------------------------------------------------------------------------------------------------ fin.
− Data/List/Extras/LazyLength.hs
@@ -1,145 +0,0 @@---- 2008.10.12: GHC 6.10 breaks -fno-warn-orphans so that it no--- longer suppresses the warnings for orphaned RULES. Hence -Werror--- will make things crash on those systems, and even if that's--- removed then -Wall will send up too many false positives which--- may disconcert users.-{-# OPTIONS_GHC -Wall -fwarn-tabs #-}---- Unfortunately GHC < 6.10 needs -fglasgow-exts in order to actually--- parse RULES (see -ddump-rules); the -frewrite-rules flag only--- enables the application of rules, instead of doing what we want.--- Apparently this is fixed in 6.10.------ http://hackage.haskell.org/trac/ghc/ticket/2213--- http://www.mail-archive.com/glasgow-haskell-users@haskell.org/msg14313.html--- OPTIONS_GHC -O2 -fglasgow-exts -frewrite-rules---------------------------------------------------------------------                                                  ~ 2009.04.02--- |--- Module      :  Data.List.Extras.LazyLength--- Copyright   :  Copyright (c) 2007--2015 wren gayle romano--- License     :  BSD3--- Maintainer  :  wren@community.haskell.org--- Stability   :  stable--- Portability :  Haskell98------ This module provides least-strict functions for getting a list's--- length and doing natural things with it.------ The regular version of @length@ will traverse the entire spine--- of the list in order to return an answer. For comparing the--- length against some bound, that is by far too strict. Being too--- strict can cause a space leak by expanding a lazy list before--- necessary (or more than is ever necessary). And it can lead to--- unnecessarily non-terminating programs when trying to determine--- if an infinite list is longer or shorter than some finite bound.------ A nicer version of @length@ would return some lazy approximation--- of an answer which retains the proper semantics. An option for--- doing this is to return Peano integers which can be decremented--- as much as necessary and no further (i.e. at most one more than--- the bound). Of course, Peano integers are woefully inefficient.--- This module provides functions with the same lazy effect but--- does so efficiently instead.------ As of version 0.3.0 the GHC rules to automatically rewrite--- certain calls to 'length' into our least-strict versions have--- been /removed/ for more consistent and predictable semantics.--- All clients should explicitly call these least-strict functions--- if they want the least-strict behavior.-------------------------------------------------------------------module Data.List.Extras.LazyLength-    ( lengthBound, lengthCompare-    ) where--------------------------------------------------------------------------------------------------------------------------------------- | A variant of 'length' which is least-strict for comparing--- against a boundary length.------ @lengthBound@ is polymorphic in the return of the helper--- function so we can use 'compare' as well as '>', '>=', '==',--- '/=', '<=', '<'. If you want to use any other functions, know--- that we only preserve the ordering of the list's length vs the--- boundary length and so the function should not rely on the true--- values of either of the numbers being compared.--lengthBound :: Int -> (Int -> Int -> a) -> [b] -> a-lengthBound n cmp xs-    | n < 0       = case xs of-                    []    -> cmp n 0-                    (_:_) -> cmp n 1-    | otherwise   = go n xs-    where-    go n' []      = cmp n' 0-    go 0  (_:_)   = cmp 0  1-    go n' (_:xs') = (go $! n'-1) xs'--{- bad RULES--- The rules themselves are correct but they alter program semantics--- regarding bottoms, depending on whether they fire or not.--"lengthBound/(>)"      forall n xs. n >  length xs = lengthBound n (>)  xs-"lengthBound/(>=)"     forall n xs. n >= length xs = lengthBound n (>=) xs-"lengthBound/(==)"     forall n xs. n == length xs = lengthBound n (==) xs-"lengthBound/(/=)"     forall n xs. n /= length xs = lengthBound n (/=) xs-"lengthBound/(<=)"     forall n xs. n <= length xs = lengthBound n (<=) xs-"lengthBound/(<)"      forall n xs. n <  length xs = lengthBound n (<)  xs-"lengthBound/compare"  forall n xs.-                          compare n (length xs) = lengthBound n compare xs--"lengthBound\\(>)"     forall n xs. length xs >  n = lengthBound n (<)  xs-"lengthBound\\(>=)"    forall n xs. length xs >= n = lengthBound n (<=) xs-"lengthBound\\(==)"    forall n xs. length xs == n = lengthBound n (==) xs-"lengthBound\\(/=)"    forall n xs. length xs /= n = lengthBound n (/=) xs-"lengthBound\\(<=)"    forall n xs. length xs <= n = lengthBound n (>=) xs-"lengthBound\\(<)"     forall n xs. length xs <  n = lengthBound n (>)  xs-"lengthBound\\compare" forall n xs.-                   compare (length xs) n = lengthBound n (flip compare) xs-    -}--------------------------------------------------------------------------------------------------------------------------------------- | A variant of 'length' which is least-strict for comparing--- the lengths of two lists. This is as strict as the length of the--- shorter list (which allows comparing an infinite list against a--- finite list).------ If you're going to immediately follow this with a 'zip' function--- then see "Data.List.Extras.Pair" instead.--lengthCompare              :: [a] -> [b] -> Ordering-lengthCompare []     []     = EQ-lengthCompare (_:_)  []     = GT-lengthCompare []     (_:_)  = LT-lengthCompare (_:xs) (_:ys) = lengthCompare xs ys---{- bad RULES--- The rules themselves are correct but they alter program semantics--- regarding bottoms, depending on whether they fire or not.--"lengthCompare/(>)"  forall xs ys.-                            length xs >  length ys = lengthCompare xs ys == GT-"lengthCompare/(>=)" forall xs ys.-                            length xs >= length ys = lengthCompare xs ys /= LT-"lengthCompare/(==)" forall xs ys.-                            length xs == length ys = lengthCompare xs ys == EQ-"lengthCompare/(/=)" forall xs ys.-                            length xs /= length ys = lengthCompare xs ys /= EQ-"lengthCompare/(<=)" forall xs ys.-                            length xs <= length ys = lengthCompare xs ys /= GT-"lengthCompare/(<)"  forall xs ys.-                            length xs <  length ys = lengthCompare xs ys == LT--"lengthCompare/compare"  forall xs ys.-                         compare (length xs) (length ys) = lengthCompare xs ys-    -}------------------------------------------------------------------------------------------------------------------------------ fin.
− Data/List/Extras/Pair.hs
@@ -1,136 +0,0 @@-{-# OPTIONS_GHC -Wall -fwarn-tabs #-}--------------------------------------------------------------------                                                  ~ 2010.11.15--- |--- Module      :  Data.List.Extras.Pair--- Copyright   :  Copyright (c) 2007--2015 wren gayle romano--- License     :  BSD3--- Maintainer  :  wren@community.haskell.org--- Stability   :  stable--- Portability :  Haskell98------ This module provides safe zipping functions which will fail--- (return 'Nothing') on uneven length lists.-------------------------------------------------------------------module Data.List.Extras.Pair-    (-    -- * Safe functions for zipping lists-      pairWithBy, pairWith, pairBy, pair-    -    -- * Special safe zipping functions-    , biject, biject'-    -    -- * New (unsafe) zipping functions-    , zipWithBy, zipBy-    ) where--------------------------------------------------------------------------------------------------------------------------------------- TODO: benchmark fusion performance of:------     foldr cons nil .: zipWith (,)---     zipWithBy (,) cons nil------ ...That is, the latter is a manual fusion of the former, but--- does zip/zipWith have a special ability to fuse with the incoming--- lists? Or can foldr fuse with consumers in ways zipWithBy can't?---- | An unsafe variant of 'pairWithBy' to fill out the interface.-zipWithBy :: (a -> b -> c)       -- tuple homomorphism-          -> (c -> d -> d) -> d  -- list  homomorphism-          -> [a] -> [b] -> d     -- a @zip@ function-{-# INLINE zipWithBy #-}--- We use the explicit lambda in order to improve inlining in ghc-7.-zipWithBy k f z = \xs ys -> zipWB xs ys id-    where-    zipWB (x:xs) (y:ys) cc = zipWB xs ys (cc . f (k x y))-    zipWB _      _      cc = cc z----- | A version of 'zip' that uses a user-defined list homomorphism.-zipBy :: ((a,b) -> d -> d) -> d -> [a] -> [b] -> d-{-# INLINE zipBy #-}-zipBy = zipWithBy (,)--------------------------------------------------------------------------------------------------------------------------------------- | A generic version of 'pair'. The first argument is a tuple--- homomorphism (i.e. a function for how to combine values from the--- two lists), the second two arguments form a list homomorphism--- (i.e. so you can 'foldr' the @[c]@ list directly without actually--- constructing it).------ In order to evaluate to WHNF 'pairWithBy' is strict in both list--- arguments, as it must be, to determine that the lists are of the--- same length. This means it can survive one infinite list (yielding--- 'Nothing') but that it can't survive two. The implementation is--- very efficient and uses a tight tail-recursive loop, however--- with extremely long lists it will be churning through heap and--- that tightness can make it hard to interrupt (lists of 1 million--- elements return in 1~2 seconds, but lists of 10 million can lock--- your system up).--pairWithBy :: (a -> b -> c)          -- @(,)@ tuple homomorphism-           -> (c -> d -> d)          -- @(:)@ list  homomorphism, pt. 1-           -> d                      -- @[]@  list  homomorphism, pt. 2-           -> [a] -> [b] -> Maybe d  -- a safer @zip@ function-{-# INLINE pairWithBy #-}--- We use the explicit lambda in order to improve inlining in ghc-7.-pairWithBy k f z = \xs ys -> pairWB xs ys id-    where-    -- N.B. Strict accumulators are usually awesome, but don't-    -- even consider it when doing CPS! Making @cc@ strict degrades-    -- performance significantly; it takes twice as long and twice-    -- as much heap just to get to WHNF. After evaluating the spine-    -- of the resulting list from 'pair' that drops to +10% time-    -- and +25% heap, which is still much worse.-    -    pairWB (x:xs) (y:ys) cc = pairWB xs ys (cc . f (k x y))-    pairWB []     []     cc = Just (cc z)-    pairWB _      _      _  = Nothing---- TODO: we could make this more general still by fusing @f@ and @k@, which we'd often want to do anyways if we're using this full form.---------------------------------------------------------------------- | A safe version of 'zipWith'.-pairWith :: (a -> b -> c) -> [a] -> [b] -> Maybe [c]-{-# INLINE pairWith #-}-pairWith f = pairWithBy f (:) []----- | A safe version of 'zip' that uses a user-defined list homomorphism.-pairBy :: ((a,b) -> d -> d) -> d -> [a] -> [b] -> Maybe d-{-# INLINE pairBy #-}-pairBy = pairWithBy (,)----- | A safe version of 'zip'.-pair :: [a] -> [b] -> Maybe [(a,b)]-{-# INLINE pair #-}-pair = pairWithBy (,) (:) []---------------------------------------------------------------------- These two are just here because they're often requested, and--- besides they're kinda cute.---- | A bijection from a list of functions and a list of arguments--- to a list of results of applying the functions bijectively.-biject :: [a -> b] -> [a] -> Maybe [b]-{-# INLINE biject #-}-biject = pairWith ($) -- 'id' also works----- | A version of 'biject' that applies functions strictly. N.B.--- the list is still lazily evaluated, this just makes the functions--- strict in their argument.-biject' :: [a -> b] -> [a] -> Maybe [b]-{-# INLINE biject' #-}-biject' = pairWith ($!)------------------------------------------------------------------------------------------------------------------------------ fin.
− Prelude/Listless.hs
@@ -1,58 +0,0 @@-{-# OPTIONS_GHC -Wall -fwarn-tabs #-}-{-# LANGUAGE CPP #-}--------------------------------------------------------------------                                                  ~ 2012.09.26--- |--- Module      :  Prelude.Listless--- Copyright   :  Copyright (c) 2007--2015 wren gayle romano--- License     :  BSD3--- Maintainer  :  wren@community.haskell.org--- Stability   :  stable--- Portability :  Haskell98 (+CPP)------ This module provides the "Prelude" but removing all the list--- functions. This is helpful for modules that overload those--- function names to work for other types. Note that on GHC 7.6 and--- above @catch@ is no longer exported from the Prelude, and also--- not re-exported from here; whereas, on earlier versions of GHC--- (and non-GHC compilers) we still re-export it.------ Be sure to disable the implicit importing of the prelude when--- you import this one (by passing @-fno-implicit-prelude@ for GHC,--- or by explicitly importing the prelude with an empty import list--- for most implementations).-------------------------------------------------------------------module Prelude.Listless-    -- We have to manually specify the exports; can't export @module-    -- Prelude@ because that'll export everything and only hide the-    -- noted parts from this module, which is meaningless.-    (($!), ($), (&&), (.), (=<<), Bool(..), Bounded(..), Char,-    Double, Either(..), Enum(..), Eq(..), FilePath, Float, Floating(..),-    Fractional(..), Functor(..), IO, IOError, Int, Integer,-    Integral(..), Maybe(..), Monad(..), Num(..), Ord(..), Ordering(..),-    Rational, Read(..), ReadS, Real(..), RealFloat(..), RealFrac(..),-    Show(..), ShowS, String, (^), (^^), appendFile, asTypeOf,-#if __GLASGOW_HASKELL__ < 706-    catch,-#endif-    const, curry, either, error, even, flip, fromIntegral, fst,-    gcd, getChar, getContents, getLine, id, interact, ioError, lcm,-    lex, maybe, not, odd, otherwise, print, putChar, putStr, putStrLn,-    read, readFile, readIO, readLn, readParen, reads, realToFrac,-    seq, showChar, showParen, showString, shows, snd, subtract,-    uncurry, undefined, until, userError, writeFile, (||))-    -    where--import Prelude hiding-    ((!!), (++), all, and, any, break, concat, concatMap, cycle,-    drop, dropWhile, elem, filter, foldl, foldl1, foldr, foldr1,-    head, init, iterate, last, length, lines, lookup, map, mapM,-    mapM_, maximum, minimum, notElem, null, or, product, repeat,-    replicate, reverse, scanl, scanl1, scanr, scanr1, sequence,-    sequence_, span, splitAt, sum, tail, take, takeWhile, unlines,-    unwords, unzip, unzip3, words, zip, zip3, zipWith, zipWith3)------------------------------------------------------------------------------------------------------------------------------ fin.
+ README.md view
@@ -0,0 +1,32 @@+list-extras+===========+[![Hackage version](https://img.shields.io/hackage/v/list-extras.svg?style=flat)](https://hackage.haskell.org/package/list-extras)+[![Build Status](https://github.com/wrengr/list-extras/workflows/ci/badge.svg)](https://github.com/wrengr/list-extras/actions?query=workflow%3Aci)+[![Dependencies](https://img.shields.io/hackage-deps/v/list-extras.svg?style=flat)](http://packdeps.haskellers.com/specific?package=list-extras)++The list-extras package provides a few common not-so-common functions+for lists.++## Install++This is a simple package and should be easy to install.  You should+be able to use the standard:++    $> cabal install list-extras++## Portability++The implementation is quite portable, relying only on a few basic+language extensions. The complete list of extensions used is:++* CPP+* Rank2Types+* ExistentialQuantification++## Links++* [Website](http://wrengr.org/)+* [Blog](http://winterkoninkje.dreamwidth.org/)+* [Twitter](https://twitter.com/wrengr)+* [Hackage](http://hackage.haskell.org/package/list-extras)+* [GitHub](https://github.com/wrengr/list-extras)
Setup.hs view
@@ -1,37 +1,7 @@ #!/usr/bin/env runhaskell  module Main (main) where---- <http://www.haskell.org/ghc/docs/latest/html/libraries/Cabal/Distribution-Simple.html> import Distribution.Simple--{--import Distribution.PackageDescription-import Distribution.Simple.LocalBuildInfo-import System.Exit-import System.Cmd-import System.Directory-import Control.Exception--withCurrentDirectory       :: FilePath -> IO a -> IO a-withCurrentDirectory path f = do-    cur <- getCurrentDirectory-    setCurrentDirectory path-    finally f (setCurrentDirectory cur)----- <http://blog.holdenkarau.com/2008/07/integrating-your-hunit-or-other-tests.html>-runTestScript :: Args-              -> Bool-              -> PackageDescription-              -> LocalBuildInfo-              -> IO ExitCode-runTestScript args flag pd lbi = withCurrentDirectory "src" (system "make")---main :: IO ()-main  = defaultMainWithHooks defaultUserHooks {runTests = runTestScript}--}  main :: IO () main  = defaultMain
list-extras.cabal view
@@ -1,19 +1,19 @@ ------------------------------------------------------------------- wren gayle romano <wren@community.haskell.org>   ~ 2015.05.30+-- wren gayle romano <wren@cpan.org>                ~ 2021.10.17 ---------------------------------------------------------------- --- By and large Cabal >=1.2 is fine; but >= 1.6 gives tested-with:--- and source-repository:.-Cabal-Version:  >= 1.6+-- Cabal >=1.10 is required by Hackage.+Cabal-Version:  >= 1.10 Build-Type:     Simple  Name:           list-extras-Version:        0.4.1.4+Version:        0.4.1.6 Stability:      stable-Homepage:       http://code.haskell.org/~wren/+Homepage:       https://wrengr.org/software/hackage.html+Bug-Reports:    https://github.com/wrengr/list-extras/issues Author:         wren gayle romano-Maintainer:     wren@community.haskell.org-Copyright:      Copyright (c) 2007--2015 wren gayle romano+Maintainer:     wren@cpan.org+Copyright:      Copyright (c) 2007–2021 wren gayle romano License:        BSD3 License-File:   LICENSE @@ -30,13 +30,23 @@                 maintain a separate package I can share the                 @Data.List.Extras.Foo@ namespace. -Tested-With:-    GHC ==6.12.1, GHC ==7.6.1, GHC ==7.8.0 Extra-source-files:-    CHANGELOG+    README.md, CHANGELOG++-- This should work as far back as GHC 6.12.1, but we don't verify that by CI.+-- <https://github.com/wrengr/list-extras/actions?query=workflow%3Aci>+Tested-With:+    GHC ==8.0.2,+    GHC ==8.2.2,+    GHC ==8.4.4,+    GHC ==8.6.5,+    GHC ==8.8.4,+    GHC ==8.10.3,+    GHC ==9.0.1+ Source-Repository head-    Type:     darcs-    Location: http://community.haskell.org/~wren/list-extras+    Type:     git+    Location: https://github.com/wrengr/list-extras.git  ---------------------------------------------------------------- Flag base4@@ -45,6 +55,8 @@  ---------------------------------------------------------------- Library+    Default-Language: Haskell2010+    Hs-Source-Dirs:  src     Exposed-Modules: Prelude.Listless                    -- , Data.List.BoehmBerarducci                    -- , Data.List.Scott
+ src/Data/List/Extras.hs view
@@ -0,0 +1,37 @@+{-# OPTIONS_GHC -Wall -fwarn-tabs #-}+----------------------------------------------------------------+--                                                  ~ 2021.10.17+-- |+-- Module      :  Data.List.Extras+-- Copyright   :  Copyright (c) 2007--2021 wren gayle romano+-- License     :  BSD3+-- Maintainer  :  wren@cpan.org+-- Stability   :  stable+-- Portability :  Haskell98+--+-- This module provides a single header for all @Data.List.Extras.*@+-- modules and provides a small number of other utility functions.+----------------------------------------------------------------++module Data.List.Extras+    (+      list+    , module Data.List.Extras.LazyLength+    , module Data.List.Extras.Pair+    , module Data.List.Extras.Argmax+    ) where++import Data.List.Extras.LazyLength+import Data.List.Extras.Pair+import Data.List.Extras.Argmax++-- | Pattern matching for lists, as a first-class function. (Could+-- also be considered as a non-recursive 'foldr'.) If the list+-- argument is @[]@ then the default argument is returned; otherwise+-- the function is called with the head and tail of the list.+list :: (a -> [a] -> b) -> b -> [a] -> b+list _ z []     = z+list f _ (x:xs) = f x xs++----------------------------------------------------------------+----------------------------------------------------------- fin.
+ src/Data/List/Extras/Argmax.hs view
@@ -0,0 +1,204 @@+{-# OPTIONS_GHC -Wall -fwarn-tabs #-}+----------------------------------------------------------------+--                                                  ~ 2021.10.17+-- |+-- Module      :  Data.List.Extras.Argmax+-- Copyright   :  Copyright (c) 2007--2021 wren gayle romano+-- License     :  BSD3+-- Maintainer  :  wren@cpan.org+-- Stability   :  experimental+-- Portability :  Haskell98+--+-- This module provides variants of the 'maximum' and 'minimum'+-- functions which return the elements for which some function is+-- maximized or minimized.+----------------------------------------------------------------++module Data.List.Extras.Argmax+    (+    -- * Utility functions+      catchNull++    -- * Generic versions+    , argmaxBy, argmaxesBy, argmaxWithMaxBy, argmaxesWithMaxBy++    -- * Maximum variations+    , argmax,   argmaxes,   argmaxWithMax,   argmaxesWithMax++    -- * Minimum variations+    , argmin,   argmins,    argminWithMin,   argminsWithMin++    {- TODO: CPS and monadic variants; argmax2, argmax3,... -}+    {- TODO: make sure argmax et al are "good consumers" for fusion -}+    ) where+-- argmaxM       :: (Monad m, Ord b) => (a -> m b) -> [a] -> m (Maybe a)++import Data.List (foldl')++----------------------------------------------------------------+----------------------------------------------------------------++-- | Apply a list function safely, i.e. when the list is non-empty.+-- All other functions will throw errors on empty lists, so use+-- this to make your own safe variations.+catchNull :: ([a] -> b) -> ([a] -> Maybe b)+{-# INLINE catchNull #-}+-- We use the explicit lambda in order to improve inlining in ghc-7.+catchNull f = \xs ->+    case xs of+    []  -> Nothing+    _:_ -> Just (f xs)+++-- | Minimize the number of string literals+emptyListError :: String -> a+{-# NOINLINE emptyListError #-}+emptyListError fun =+    error $ "Data.List.Extras.Argmax."++fun++": empty list"+++-- | Apply a list function unsafely. For internal use.+throwNull :: String -> (a -> [a] -> b) -> ([a] -> b)+{-# INLINE throwNull #-}+-- We use the explicit lambda in order to improve inlining in ghc-7.+throwNull fun f = \xs ->+    case xs of+    []    -> emptyListError fun+    x:xs' -> f x xs'++----------------------------------------------------------------+----------------------------------------------------------------+-- | Tail-recursive driver+_argmaxWithMaxBy :: (b -> b -> Bool) -> (a -> b) -> a -> [a] -> (a,b)+{-# INLINE _argmaxWithMaxBy #-}+-- We use the explicit lambda in order to improve inlining in ghc-7.+_argmaxWithMaxBy isBetterThan f =+    \x xs -> foldl' cmp (x, f x) xs+    where+    cmp bfb@(_,fb) a =+        let  fa = f a in+        if   fa `isBetterThan` fb+        then (a,fa)+        else bfb+++-- | Tail-recursive driver+_argmaxesWithMaxBy :: (b -> b -> Ordering) -> (a -> b) -> a -> [a] -> ([a],b)+{-# INLINE _argmaxesWithMaxBy #-}+-- We use the explicit lambda in order to improve inlining in ghc-7.+_argmaxesWithMaxBy isBetterEqualThan f =+    \x xs -> foldl' cmp ([x], f x) xs+    where+    cmp bsfb@(bs,fb) a =+        let  fa = f a in+        case isBetterEqualThan fa fb of+             GT -> ([a],  fa)+             EQ -> (a:bs, fb)+             _  -> bsfb+++_argmaxBy :: (b -> b -> Bool) -> (a -> b) -> a -> [a] -> a+{-# INLINE _argmaxBy #-}+-- We use the point-free style in order to improve inlining in ghc-7.+_argmaxBy k f = (fst .) . _argmaxWithMaxBy k f+++_argmaxesBy :: (b -> b -> Ordering) -> (a -> b) -> a -> [a] -> [a]+{-# INLINE _argmaxesBy #-}+-- We use the point-free style in order to improve inlining in ghc-7.+_argmaxesBy k f = (fst .) . _argmaxesWithMaxBy k f++----------------------------------------------------------------+----------------------------------------------------------------++bool    :: (a -> a -> Ordering) -> (a -> a -> Bool)+bool ord = \a b -> ord a b == GT+++-- | Return an element of the list which maximizes the function+-- according to a user-defined ordering.+argmaxBy        :: (b -> b -> Ordering) -> (a -> b) -> [a] -> a+argmaxBy   ord f = throwNull "argmaxBy"+                 $ _argmaxBy (bool ord) f+++-- | Return all elements of the list which maximize the function+-- according to a user-defined ordering.+argmaxesBy      :: (b -> b -> Ordering) -> (a -> b) -> [a] -> [a]+argmaxesBy ord f = throwNull "argmaxesBy"+                 $ _argmaxesBy ord f+++-- | Return an element of the list which maximizes the function+-- according to a user-defined ordering, and return the value of+-- the function at that element as well.+argmaxWithMaxBy        :: (b -> b -> Ordering) -> (a -> b) -> [a] -> (a, b)+argmaxWithMaxBy   ord f = throwNull "argmaxWithMaxBy"+                        $ _argmaxWithMaxBy (bool ord) f+++-- | Return all elements of the list which maximize the function+-- according to a user-defined ordering, and return the value of+-- the function at those elements as well.+argmaxesWithMaxBy      :: (b -> b -> Ordering) -> (a -> b) -> [a] -> ([a], b)+argmaxesWithMaxBy ord f = throwNull "argmaxesWithMaxBy"+                        $ _argmaxesWithMaxBy ord f++----------------------------------------------------------------+-- SPECIALIZE on b \in {Int,Integer,Float,Double} for the four+-- functions below nearly doubles the library size (about +21kB).+-- For a basic utility library that's a bit excessive, though if+-- we break the argmax stuff out from list-extras then we might go+-- through with it for performance sake.++-- | Return an element of the list which maximizes the function.+argmax    :: (Ord b) => (a -> b) -> [a] -> a+argmax   f = throwNull "argmax"+           $ _argmaxBy (>) f++-- | Return all elements of the list which maximize the function.+argmaxes  :: (Ord b) => (a -> b) -> [a] -> [a]+argmaxes f = throwNull "argmaxes"+           $ _argmaxesBy compare f+++-- | Return an element of the list which maximizes the function,+-- and return the value of the function at that element as well.+argmaxWithMax    :: (Ord b) => (a -> b) -> [a] -> (a, b)+argmaxWithMax   f = throwNull "argmaxWithMax"+                  $ _argmaxWithMaxBy (>) f+++-- | Return all elements of the list which maximize the function,+-- and return the value of the function at those elements as well.+argmaxesWithMax  :: (Ord b) => (a -> b) -> [a] -> ([a], b)+argmaxesWithMax f = throwNull "argmaxesWithMax"+                  $ _argmaxesWithMaxBy compare f++----------------------------------------------------------------++-- | Return an element of the list which minimizes the function.+argmin   :: (Ord b) => (a -> b) -> [a] -> a+argmin  f = throwNull "argmax"+          $ _argmaxBy (<) f++-- | Return all elements of the list which minimize the function.+argmins  :: (Ord b) => (a -> b) -> [a] -> [a]+argmins f = throwNull "argmins"+          $ _argmaxesBy (flip compare) f+++-- | Return an element of the list which minimizes the function,+-- and return the value of the function at that element as well.+argminWithMin   :: (Ord b) => (a -> b) -> [a] -> (a, b)+argminWithMin  f = throwNull "argminWithMin"+                 $ _argmaxWithMaxBy (<) f++-- | Return all elements of the list which minimize the function,+-- and return the value of the function at those elements as well.+argminsWithMin  :: (Ord b) => (a -> b) -> [a] -> ([a], b)+argminsWithMin f = throwNull "argminsWithMin"+                 $ _argmaxesWithMaxBy (flip compare) f++----------------------------------------------------------------+----------------------------------------------------------- fin.
+ src/Data/List/Extras/LazyLength.hs view
@@ -0,0 +1,145 @@++-- 2008.10.12: GHC 6.10 breaks -fno-warn-orphans so that it no+-- longer suppresses the warnings for orphaned RULES. Hence -Werror+-- will make things crash on those systems, and even if that's+-- removed then -Wall will send up too many false positives which+-- may disconcert users.+{-# OPTIONS_GHC -Wall -fwarn-tabs #-}++-- Unfortunately GHC < 6.10 needs -fglasgow-exts in order to actually+-- parse RULES (see -ddump-rules); the -frewrite-rules flag only+-- enables the application of rules, instead of doing what we want.+-- Apparently this is fixed in 6.10.+--+-- http://hackage.haskell.org/trac/ghc/ticket/2213+-- http://www.mail-archive.com/glasgow-haskell-users@haskell.org/msg14313.html+-- OPTIONS_GHC -O2 -fglasgow-exts -frewrite-rules++----------------------------------------------------------------+--                                                  ~ 2021.10.17+-- |+-- Module      :  Data.List.Extras.LazyLength+-- Copyright   :  Copyright (c) 2007--2021 wren gayle romano+-- License     :  BSD3+-- Maintainer  :  wren@cpan.org+-- Stability   :  stable+-- Portability :  Haskell98+--+-- This module provides least-strict functions for getting a list's+-- length and doing natural things with it.+--+-- The regular version of @length@ will traverse the entire spine+-- of the list in order to return an answer. For comparing the+-- length against some bound, that is by far too strict. Being too+-- strict can cause a space leak by expanding a lazy list before+-- necessary (or more than is ever necessary). And it can lead to+-- unnecessarily non-terminating programs when trying to determine+-- if an infinite list is longer or shorter than some finite bound.+--+-- A nicer version of @length@ would return some lazy approximation+-- of an answer which retains the proper semantics. An option for+-- doing this is to return Peano integers which can be decremented+-- as much as necessary and no further (i.e. at most one more than+-- the bound). Of course, Peano integers are woefully inefficient.+-- This module provides functions with the same lazy effect but+-- does so efficiently instead.+--+-- As of version 0.3.0 the GHC rules to automatically rewrite+-- certain calls to 'length' into our least-strict versions have+-- been /removed/ for more consistent and predictable semantics.+-- All clients should explicitly call these least-strict functions+-- if they want the least-strict behavior.+----------------------------------------------------------------++module Data.List.Extras.LazyLength+    ( lengthBound, lengthCompare+    ) where+++----------------------------------------------------------------+----------------------------------------------------------------+-- | A variant of 'length' which is least-strict for comparing+-- against a boundary length.+--+-- @lengthBound@ is polymorphic in the return of the helper+-- function so we can use 'compare' as well as '>', '>=', '==',+-- '/=', '<=', '<'. If you want to use any other functions, know+-- that we only preserve the ordering of the list's length vs the+-- boundary length and so the function should not rely on the true+-- values of either of the numbers being compared.++lengthBound :: Int -> (Int -> Int -> a) -> [b] -> a+lengthBound n cmp xs+    | n < 0       = case xs of+                    []    -> cmp n 0+                    (_:_) -> cmp n 1+    | otherwise   = go n xs+    where+    go n' []      = cmp n' 0+    go 0  (_:_)   = cmp 0  1+    go n' (_:xs') = (go $! n'-1) xs'++{- bad RULES+-- The rules themselves are correct but they alter program semantics+-- regarding bottoms, depending on whether they fire or not.++"lengthBound/(>)"      forall n xs. n >  length xs = lengthBound n (>)  xs+"lengthBound/(>=)"     forall n xs. n >= length xs = lengthBound n (>=) xs+"lengthBound/(==)"     forall n xs. n == length xs = lengthBound n (==) xs+"lengthBound/(/=)"     forall n xs. n /= length xs = lengthBound n (/=) xs+"lengthBound/(<=)"     forall n xs. n <= length xs = lengthBound n (<=) xs+"lengthBound/(<)"      forall n xs. n <  length xs = lengthBound n (<)  xs+"lengthBound/compare"  forall n xs.+                          compare n (length xs) = lengthBound n compare xs++"lengthBound\\(>)"     forall n xs. length xs >  n = lengthBound n (<)  xs+"lengthBound\\(>=)"    forall n xs. length xs >= n = lengthBound n (<=) xs+"lengthBound\\(==)"    forall n xs. length xs == n = lengthBound n (==) xs+"lengthBound\\(/=)"    forall n xs. length xs /= n = lengthBound n (/=) xs+"lengthBound\\(<=)"    forall n xs. length xs <= n = lengthBound n (>=) xs+"lengthBound\\(<)"     forall n xs. length xs <  n = lengthBound n (>)  xs+"lengthBound\\compare" forall n xs.+                   compare (length xs) n = lengthBound n (flip compare) xs+    -}+++----------------------------------------------------------------+----------------------------------------------------------------+-- | A variant of 'length' which is least-strict for comparing+-- the lengths of two lists. This is as strict as the length of the+-- shorter list (which allows comparing an infinite list against a+-- finite list).+--+-- If you're going to immediately follow this with a 'zip' function+-- then see "Data.List.Extras.Pair" instead.++lengthCompare              :: [a] -> [b] -> Ordering+lengthCompare []     []     = EQ+lengthCompare (_:_)  []     = GT+lengthCompare []     (_:_)  = LT+lengthCompare (_:xs) (_:ys) = lengthCompare xs ys+++{- bad RULES+-- The rules themselves are correct but they alter program semantics+-- regarding bottoms, depending on whether they fire or not.++"lengthCompare/(>)"  forall xs ys.+                            length xs >  length ys = lengthCompare xs ys == GT+"lengthCompare/(>=)" forall xs ys.+                            length xs >= length ys = lengthCompare xs ys /= LT+"lengthCompare/(==)" forall xs ys.+                            length xs == length ys = lengthCompare xs ys == EQ+"lengthCompare/(/=)" forall xs ys.+                            length xs /= length ys = lengthCompare xs ys /= EQ+"lengthCompare/(<=)" forall xs ys.+                            length xs <= length ys = lengthCompare xs ys /= GT+"lengthCompare/(<)"  forall xs ys.+                            length xs <  length ys = lengthCompare xs ys == LT++"lengthCompare/compare"  forall xs ys.+                         compare (length xs) (length ys) = lengthCompare xs ys+    -}++----------------------------------------------------------------+----------------------------------------------------------- fin.
+ src/Data/List/Extras/Pair.hs view
@@ -0,0 +1,136 @@+{-# OPTIONS_GHC -Wall -fwarn-tabs #-}+----------------------------------------------------------------+--                                                  ~ 2021.10.17+-- |+-- Module      :  Data.List.Extras.Pair+-- Copyright   :  Copyright (c) 2007--2021 wren gayle romano+-- License     :  BSD3+-- Maintainer  :  wren@cpan.org+-- Stability   :  stable+-- Portability :  Haskell98+--+-- This module provides safe zipping functions which will fail+-- (return 'Nothing') on uneven length lists.+----------------------------------------------------------------++module Data.List.Extras.Pair+    (+    -- * Safe functions for zipping lists+      pairWithBy, pairWith, pairBy, pair++    -- * Special safe zipping functions+    , biject, biject'++    -- * New (unsafe) zipping functions+    , zipWithBy, zipBy+    ) where+++----------------------------------------------------------------+----------------------------------------------------------------+-- TODO: benchmark fusion performance of:+--+--     foldr cons nil .: zipWith (,)+--     zipWithBy (,) cons nil+--+-- ...That is, the latter is a manual fusion of the former, but+-- does zip/zipWith have a special ability to fuse with the incoming+-- lists? Or can foldr fuse with consumers in ways zipWithBy can't?++-- | An unsafe variant of 'pairWithBy' to fill out the interface.+zipWithBy :: (a -> b -> c)       -- tuple homomorphism+          -> (c -> d -> d) -> d  -- list  homomorphism+          -> [a] -> [b] -> d     -- a @zip@ function+{-# INLINE zipWithBy #-}+-- We use the explicit lambda in order to improve inlining in ghc-7.+zipWithBy k f z = \xs ys -> zipWB xs ys id+    where+    zipWB (x:xs) (y:ys) cc = zipWB xs ys (cc . f (k x y))+    zipWB _      _      cc = cc z+++-- | A version of 'zip' that uses a user-defined list homomorphism.+zipBy :: ((a,b) -> d -> d) -> d -> [a] -> [b] -> d+{-# INLINE zipBy #-}+zipBy = zipWithBy (,)+++----------------------------------------------------------------+----------------------------------------------------------------+-- | A generic version of 'pair'. The first argument is a tuple+-- homomorphism (i.e. a function for how to combine values from the+-- two lists), the second two arguments form a list homomorphism+-- (i.e. so you can 'foldr' the @[c]@ list directly without actually+-- constructing it).+--+-- In order to evaluate to WHNF 'pairWithBy' is strict in both list+-- arguments, as it must be, to determine that the lists are of the+-- same length. This means it can survive one infinite list (yielding+-- 'Nothing') but that it can't survive two. The implementation is+-- very efficient and uses a tight tail-recursive loop, however+-- with extremely long lists it will be churning through heap and+-- that tightness can make it hard to interrupt (lists of 1 million+-- elements return in 1~2 seconds, but lists of 10 million can lock+-- your system up).++pairWithBy :: (a -> b -> c)          -- @(,)@ tuple homomorphism+           -> (c -> d -> d)          -- @(:)@ list  homomorphism, pt. 1+           -> d                      -- @[]@  list  homomorphism, pt. 2+           -> [a] -> [b] -> Maybe d  -- a safer @zip@ function+{-# INLINE pairWithBy #-}+-- We use the explicit lambda in order to improve inlining in ghc-7.+pairWithBy k f z = \xs ys -> pairWB xs ys id+    where+    -- N.B. Strict accumulators are usually awesome, but don't+    -- even consider it when doing CPS! Making @cc@ strict degrades+    -- performance significantly; it takes twice as long and twice+    -- as much heap just to get to WHNF. After evaluating the spine+    -- of the resulting list from 'pair' that drops to +10% time+    -- and +25% heap, which is still much worse.++    pairWB (x:xs) (y:ys) cc = pairWB xs ys (cc . f (k x y))+    pairWB []     []     cc = Just (cc z)+    pairWB _      _      _  = Nothing++-- TODO: we could make this more general still by fusing @f@ and @k@, which we'd often want to do anyways if we're using this full form.++----------------------------------------------------------------++-- | A safe version of 'zipWith'.+pairWith :: (a -> b -> c) -> [a] -> [b] -> Maybe [c]+{-# INLINE pairWith #-}+pairWith f = pairWithBy f (:) []+++-- | A safe version of 'zip' that uses a user-defined list homomorphism.+pairBy :: ((a,b) -> d -> d) -> d -> [a] -> [b] -> Maybe d+{-# INLINE pairBy #-}+pairBy = pairWithBy (,)+++-- | A safe version of 'zip'.+pair :: [a] -> [b] -> Maybe [(a,b)]+{-# INLINE pair #-}+pair = pairWithBy (,) (:) []+++----------------------------------------------------------------+-- These two are just here because they're often requested, and+-- besides they're kinda cute.++-- | A bijection from a list of functions and a list of arguments+-- to a list of results of applying the functions bijectively.+biject :: [a -> b] -> [a] -> Maybe [b]+{-# INLINE biject #-}+biject = pairWith ($) -- 'id' also works+++-- | A version of 'biject' that applies functions strictly. N.B.+-- the list is still lazily evaluated, this just makes the functions+-- strict in their argument.+biject' :: [a -> b] -> [a] -> Maybe [b]+{-# INLINE biject' #-}+biject' = pairWith ($!)++----------------------------------------------------------------+----------------------------------------------------------- fin.
+ src/Prelude/Listless.hs view
@@ -0,0 +1,58 @@+{-# OPTIONS_GHC -Wall -fwarn-tabs #-}+{-# LANGUAGE CPP #-}+----------------------------------------------------------------+--                                                  ~ 2021.10.17+-- |+-- Module      :  Prelude.Listless+-- Copyright   :  Copyright (c) 2007--2021 wren gayle romano+-- License     :  BSD3+-- Maintainer  :  wren@cpan.org+-- Stability   :  stable+-- Portability :  Haskell98 (+CPP)+--+-- This module provides the "Prelude" but removing all the list+-- functions. This is helpful for modules that overload those+-- function names to work for other types. Note that on GHC 7.6 and+-- above @catch@ is no longer exported from the Prelude, and also+-- not re-exported from here; whereas, on earlier versions of GHC+-- (and non-GHC compilers) we still re-export it.+--+-- Be sure to disable the implicit importing of the prelude when+-- you import this one (by passing @-fno-implicit-prelude@ for GHC,+-- or by explicitly importing the prelude with an empty import list+-- for most implementations).+----------------------------------------------------------------++module Prelude.Listless+    -- We have to manually specify the exports; can't export @module+    -- Prelude@ because that'll export everything and only hide the+    -- noted parts from this module, which is meaningless.+    (($!), ($), (&&), (.), (=<<), Bool(..), Bounded(..), Char,+    Double, Either(..), Enum(..), Eq(..), FilePath, Float, Floating(..),+    Fractional(..), Functor(..), IO, IOError, Int, Integer,+    Integral(..), Maybe(..), Monad(..), Num(..), Ord(..), Ordering(..),+    Rational, Read(..), ReadS, Real(..), RealFloat(..), RealFrac(..),+    Show(..), ShowS, String, (^), (^^), appendFile, asTypeOf,+#if __GLASGOW_HASKELL__ < 706+    catch,+#endif+    const, curry, either, error, even, flip, fromIntegral, fst,+    gcd, getChar, getContents, getLine, id, interact, ioError, lcm,+    lex, maybe, not, odd, otherwise, print, putChar, putStr, putStrLn,+    read, readFile, readIO, readLn, readParen, reads, realToFrac,+    seq, showChar, showParen, showString, shows, snd, subtract,+    uncurry, undefined, until, userError, writeFile, (||))++    where++import Prelude hiding+    ((!!), (++), all, and, any, break, concat, concatMap, cycle,+    drop, dropWhile, elem, filter, foldl, foldl1, foldr, foldr1,+    head, init, iterate, last, length, lines, lookup, map, mapM,+    mapM_, maximum, minimum, notElem, null, or, product, repeat,+    replicate, reverse, scanl, scanl1, scanr, scanr1, sequence,+    sequence_, span, splitAt, sum, tail, take, takeWhile, unlines,+    unwords, unzip, unzip3, words, zip, zip3, zipWith, zipWith3)++----------------------------------------------------------------+----------------------------------------------------------- fin.