From 0f1a548129a93e556114c0cd6d7ae472978f286d Mon Sep 17 00:00:00 2001 From: How Si Wei Date: Tue, 28 Nov 2017 06:56:38 +0800 Subject: [PATCH 1/6] Export applicative version of Foldable and Traversable functions --- BasicPrelude.hs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/BasicPrelude.hs b/BasicPrelude.hs index f852963..baa88d6 100644 --- a/BasicPrelude.hs +++ b/BasicPrelude.hs @@ -28,6 +28,9 @@ module BasicPrelude , elem , maximum , minimum + , traverse_ + , sequenceA_ + , for_ , Traversable ( traverse @@ -35,6 +38,7 @@ module BasicPrelude , mapM , sequence ) + , for -- * Enhanced exports -- ** Simpler name for a typeclassed operation @@ -137,8 +141,8 @@ import Control.Monad hiding ) -import Data.Foldable (Foldable(..), elem, maximum, minimum) -import Data.Traversable (Traversable(..)) +import Data.Foldable (Foldable(..), elem, maximum, minimum, traverse_, sequenceA_, for_) +import Data.Traversable (Traversable(..), for) import qualified Data.Text as Text import qualified Data.Text.IO as Text import qualified Data.Text.Lazy as LText From cccc319d2c49dca938f8065a6f76434ce063abbc Mon Sep 17 00:00:00 2001 From: How Si Wei Date: Tue, 28 Nov 2017 10:22:56 +0800 Subject: [PATCH 2/6] Generalize all IO functions to MonadIO --- BasicPrelude.hs | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/BasicPrelude.hs b/BasicPrelude.hs index baa88d6..94b3a04 100644 --- a/BasicPrelude.hs +++ b/BasicPrelude.hs @@ -74,9 +74,9 @@ module BasicPrelude , encodeUtf8 , decodeUtf8 -- ** Text operations (IO) - , Text.getLine - , LText.getContents - , LText.interact + , getLine + , getContents + , interact -- * Miscellaneous prelude re-exports -- ** Math @@ -97,9 +97,9 @@ module BasicPrelude , Prelude.lex , readMay -- ** IO operations - , Prelude.putChar - , Prelude.getChar - , Prelude.readLn + , getChar + , putChar + , readLn ) where import CorePrelude @@ -204,23 +204,23 @@ read = Prelude.read . Text.unpack -- | The readIO function is similar to read -- except that it signals parse failure to the IO monad -- instead of terminating the program. -readIO :: Read a => Text -> IO a -readIO = Prelude.readIO . Text.unpack +readIO :: (MonadIO m, Read a) => Text -> m a +readIO = liftIO . Prelude.readIO . Text.unpack -- | Read a file and return the contents of the file as Text. -- The entire file is read strictly. -readFile :: FilePath -> IO Text -readFile = Text.readFile +readFile :: MonadIO m => FilePath -> m Text +readFile = liftIO . Text.readFile -- | Write Text to a file. -- The file is truncated to zero length before writing begins. -writeFile :: FilePath -> Text -> IO () -writeFile = Text.writeFile +writeFile :: MonadIO m => FilePath -> Text -> m () +writeFile p = liftIO . Text.writeFile p -- | Write Text to the end of a file. -appendFile :: FilePath -> Text -> IO () -appendFile = Text.appendFile +appendFile :: MonadIO m => FilePath -> Text -> m () +appendFile p = liftIO . Text.appendFile p textToString :: Text -> Prelude.String textToString = Text.unpack @@ -254,5 +254,24 @@ fpToString = id decodeUtf8 :: ByteString -> Text decodeUtf8 = decodeUtf8With lenientDecode +getLine :: MonadIO m => m Text +getLine = liftIO Text.getLine + +getContents :: MonadIO m => m LText +getContents = liftIO LText.getContents + +interact :: MonadIO m => (LText -> LText) -> m () +interact = liftIO . LText.interact + readMay :: Read a => Text -> Maybe a readMay = Safe.readMay . Text.unpack + +getChar :: MonadIO m => m Char +getChar = liftIO Prelude.getChar + +putChar :: MonadIO m => Char -> m () +putChar = liftIO . Prelude.putChar + +-- | The 'readLn' function combines 'getLine' and 'readIO'. +readLn :: (MonadIO m, Read a) => m a +readLn = liftIO Prelude.readLn From 9693129942fc7a0bde8e8b5732157539c62824c6 Mon Sep 17 00:00:00 2001 From: How Si Wei Date: Tue, 28 Nov 2017 11:54:41 +0800 Subject: [PATCH 3/6] Use foldl1 for maximumBy and minimumBy So that GHC can convert them to be strict [https://ghc.haskell.org/trac/ghc/ticket/14527] --- BasicPrelude.hs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/BasicPrelude.hs b/BasicPrelude.hs index 94b3a04..3cbdfbe 100644 --- a/BasicPrelude.hs +++ b/BasicPrelude.hs @@ -1,4 +1,5 @@ {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE CPP #-} -- | BasicPrelude mostly re-exports -- several key libraries in their entirety. @@ -31,6 +32,8 @@ module BasicPrelude , traverse_ , sequenceA_ , for_ + , maximumBy + , minimumBy , Traversable ( traverse @@ -129,6 +132,8 @@ import Data.List hiding , foldr1 , maximum , minimum + , maximumBy + , minimumBy ) -- Import *all of the things* from Control.Monad, @@ -152,6 +157,22 @@ import Data.Text.Encoding (encodeUtf8, decodeUtf8With) import Data.Text.Encoding.Error (lenientDecode) import qualified Safe +#if MIN_VERSION_base(4,10,0) +import Data.Foldable (maximumBy, minimumBy) +#else +maximumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a +maximumBy cmp = foldl1 max' + where max' x y = case cmp x y of + GT -> x + _ -> y + +minimumBy :: Foldable t => (a -> a -> Ordering) -> t a -> a +minimumBy cmp = foldl1 min' + where min' x y = case cmp x y of + GT -> y + _ -> x +#endif + -- | > map = fmap map :: (Functor f) => (a -> b) -> f a -> f b map = fmap From b1990b9b2017d3dcc4ea711874d32b7ab39ad21c Mon Sep 17 00:00:00 2001 From: How Si Wei Date: Tue, 28 Nov 2017 13:01:18 +0800 Subject: [PATCH 4/6] Remove nonexistent foldr' from Data.List hidings --- BasicPrelude.hs | 1 - 1 file changed, 1 deletion(-) diff --git a/BasicPrelude.hs b/BasicPrelude.hs index 3cbdfbe..f508f15 100644 --- a/BasicPrelude.hs +++ b/BasicPrelude.hs @@ -128,7 +128,6 @@ import Data.List hiding , foldl' , foldl1 , foldr - , foldr' , foldr1 , maximum , minimum From f2cbc8787d9263f3913cde6d27923806a2b4813a Mon Sep 17 00:00:00 2001 From: How Si Wei Date: Sun, 3 Dec 2017 20:13:03 +0800 Subject: [PATCH 5/6] Update changelog, version bump --- ChangeLog.md | 7 +++++++ basic-prelude.cabal | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 31cd9b4..a69ec61 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,10 @@ +## 0.7.0 + +* Export applicative version of Foldable and Traversable functions [#72](https://github.com/snoyberg/basic-prelude/issues/72) +* Generalize all IO functions to MonadIO [#75](https://github.com/snoyberg/basic-prelude/issues/75) +* Use `foldl1` for `maximumBy` and `minimumBy` [#74](https://github.com/snoyberg/basic-prelude/issues/74) +* Remove nonexistent `foldr'` from `Data.List` hiding list + ## 0.6.1.1 * Add `HasCallStack` for `terror` diff --git a/basic-prelude.cabal b/basic-prelude.cabal index 875fa17..9186928 100644 --- a/basic-prelude.cabal +++ b/basic-prelude.cabal @@ -1,5 +1,5 @@ name: basic-prelude -version: 0.6.1.1 +version: 0.7.0 synopsis: An enhanced core prelude; a common foundation for alternate preludes. description: The premise of @basic-prelude@ is that there are a lot of very commonly desired features missing from the standard @Prelude@, such as commonly used operators (@\<$\>@ and @>=>@, for instance) and imports for common datatypes (e.g., @ByteString@ and @Vector@). At the same time, there are lots of other components which are more debatable, such as providing polymorphic versions of common functions. From 790bbee7444e061279c2c92920906398b3797cbd Mon Sep 17 00:00:00 2001 From: How Si Wei Date: Mon, 4 Dec 2017 19:22:26 +0800 Subject: [PATCH 6/6] Add @since comments --- BasicPrelude.hs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/BasicPrelude.hs b/BasicPrelude.hs index f508f15..6b8adb8 100644 --- a/BasicPrelude.hs +++ b/BasicPrelude.hs @@ -224,21 +224,29 @@ read = Prelude.read . Text.unpack -- | The readIO function is similar to read -- except that it signals parse failure to the IO monad -- instead of terminating the program. +-- +-- @since 0.7.0 readIO :: (MonadIO m, Read a) => Text -> m a readIO = liftIO . Prelude.readIO . Text.unpack -- | Read a file and return the contents of the file as Text. -- The entire file is read strictly. +-- +-- @since 0.7.0 readFile :: MonadIO m => FilePath -> m Text readFile = liftIO . Text.readFile -- | Write Text to a file. -- The file is truncated to zero length before writing begins. +-- +-- @since 0.7.0 writeFile :: MonadIO m => FilePath -> Text -> m () writeFile p = liftIO . Text.writeFile p -- | Write Text to the end of a file. +-- +-- @since 0.7.0 appendFile :: MonadIO m => FilePath -> Text -> m () appendFile p = liftIO . Text.appendFile p @@ -274,24 +282,36 @@ fpToString = id decodeUtf8 :: ByteString -> Text decodeUtf8 = decodeUtf8With lenientDecode +-- | +-- @since 0.7.0 getLine :: MonadIO m => m Text getLine = liftIO Text.getLine +-- | +-- @since 0.7.0 getContents :: MonadIO m => m LText getContents = liftIO LText.getContents +-- | +-- @since 0.7.0 interact :: MonadIO m => (LText -> LText) -> m () interact = liftIO . LText.interact readMay :: Read a => Text -> Maybe a readMay = Safe.readMay . Text.unpack +-- | +-- @since 0.7.0 getChar :: MonadIO m => m Char getChar = liftIO Prelude.getChar +-- | +-- @since 0.7.0 putChar :: MonadIO m => Char -> m () putChar = liftIO . Prelude.putChar -- | The 'readLn' function combines 'getLine' and 'readIO'. +-- +-- @since 0.7.0 readLn :: (MonadIO m, Read a) => m a readLn = liftIO Prelude.readLn