Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NO-ISSUE] Add traverse_ to Prelude! #6

Merged
merged 10 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@ jobs:
strategy:
matrix:
ghc:
- 8.10.7
- 9.2.3
- 9.2.4
steps:
- uses: actions/checkout@v3
- uses: haskell/actions/setup@v2
id: setup-haskell
with:
ghc-version: ${{ matrix.ghc }}
cabal-version: 3.6.2.0
cabal-version: 3.8.1.0
- name: Create freeze file
run: cabal freeze
- uses: actions/cache@v3
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/formatting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Formatting

on:
pull_request:
paths:
- "src/**.hs"
- scrive-prelude.cabal
- .github/workflows/build.yaml
push:
branches:
- main

jobs:
fourmolu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: fourmolu/fourmolu-action@v5
with:
pattern: |
src/**/*.hs
11 changes: 11 additions & 0 deletions fourmolu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
indentation: 2
function-arrows: leading # where to place arrows in type signatures
comma-style: leading # for lists, tuples etc. - can also be 'trailing'
import-export-style: leading
indent-wheres: true # 'false' means save space by only half-indenting the 'where' keyword
record-brace-space: true # rec {x = 1} vs. rec{x = 1}
newlines-between-decls: 1 # number of newlines between top-level declarations
haddock-style: single-line # '--' vs. '{-'
let-style: inline
in-style: left-align
respectful: true # don't be too opinionated about newlines etc
225 changes: 152 additions & 73 deletions src/Prelude.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
-- | Slightly customized replacement of Prelude.
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE PackageImports #-}
module Prelude (
module Control.Applicative
{-# OPTIONS_GHC -fno-warn-orphans #-}

-- | Slightly customized replacement of Prelude.
module Prelude
( module Control.Applicative
, module Control.Monad
, module Data.Algebra.Boolean
, module Data.Either
Expand All @@ -18,88 +19,161 @@ module Prelude (
, MonadFail (..)
, (!!)
-- optics
, (&), (%), (?~)
, view, (^.)
, preview, (^?)
, toListOf, (^..)
, over, (%~)
, set, (.~)
, (&)
, (%)
, (?~)
, view
, (^.)
, preview
, (^?)
, toListOf
, (^..)
, over
, (%~)
, set
, (.~)
, copy
-- prelude
, identity
, expectJust
, for
, maybeRead
, toMaybe
, fromJust
, head
, identity
, last
, maximum
, maybeRead
, minimum
, read
, showt
, showtp
, tail
, expectJust
, fromJust
, throwLeft
, toMaybe
, unexpectedError
, whenJust
, whenNothing
, unexpectedError
, throwLeft
, showt
, showtp
) where
)
where

import Control.Applicative
import Control.Exception (Exception)
import Control.Monad hiding (fail)
import Control.Monad.Catch (MonadThrow(..))
import Control.Monad.Catch (MonadThrow (..))
import Control.Monad.Extra hiding (fail)
import Control.Monad.Fail (MonadFail(..))
import Control.Monad.Fail (MonadFail (..))
import Data.Algebra.Boolean
import Data.Either
import Data.Foldable (asum, foldMap)
import qualified Data.Either.Optics as O
import Data.Foldable (asum, foldMap, traverse_)
import Data.List hiding
( (!!), all, and, any, head, last, maximum, minimum, or, tail
( all
, and
, any
, head
, last
, maximum
, minimum
, or
, tail
, (!!)
)
import Data.Maybe hiding (fromJust)
import qualified Data.Maybe.Optics as O
import Data.Monoid
import Data.Monoid.Utils
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Tuple.Optics as O
import GHC.Generics (Generic)
import GHC.Stack (HasCallStack, withFrozenCallStack)
import Optics
import qualified Optics as O
( A_Fold
, A_Getter
, A_Lens
, A_Prism
, A_ReversedLens
, A_ReversedPrism
, A_Review
, A_Setter
, A_Traversal
, AffineFold
, AffineTraversal
, AffineTraversal'
, An_AffineFold
, An_AffineTraversal
, An_Iso
, Fold
, Getter
, Iso
, Iso'
, IxAffineFold
, IxAffineTraversal
, IxAffineTraversal'
, IxFold
, IxGetter
, IxLens
, IxLens'
, IxSetter
, IxSetter'
, IxTraversal
, IxTraversal'
, Lens
, Lens'
, NoIx
, Optic
, Optic'
, Prism
, Prism'
, ReversedLens
, ReversedLens'
, ReversedPrism
, ReversedPrism'
, Review
, Setter
, Setter'
, Traversal
, Traversal'
, WithIx
)
import Text.JSON.FromJSValue
import Text.JSON.ToJSValue
import Text.Pretty.Simple
( OutputOptions(..), defaultOutputOptionsDarkBg, pShowOpt
( OutputOptions (..)
, defaultOutputOptionsDarkBg
, pShowOpt
)
import "base" Prelude hiding
( (!!), (&&), (||), all, and, any, error, fail, head, id, last, maximum
, minimum, not, or, read, tail
)
import qualified Data.Either.Optics as O
import qualified Data.Maybe.Optics as O
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Tuple.Optics as O
import qualified Optics as O
( A_Fold, A_Getter, A_Lens, A_Prism, A_ReversedLens, A_ReversedPrism, A_Review
, A_Setter, A_Traversal, AffineFold, AffineTraversal, AffineTraversal'
, An_AffineFold, An_AffineTraversal, An_Iso, Fold, Getter, Iso, Iso'
, IxAffineFold, IxAffineTraversal, IxAffineTraversal', IxFold, IxGetter
, IxLens, IxLens', IxSetter, IxSetter', IxTraversal, IxTraversal', Lens, Lens'
, NoIx, Optic, Optic', Prism, Prism', ReversedLens, ReversedLens'
, ReversedPrism, ReversedPrism', Review, Setter, Setter', Traversal
, Traversal', WithIx
( all
, and
, any
, error
, fail
, head
, id
, last
, maximum
, minimum
, not
, or
, read
, tail
, (!!)
, (&&)
, (||)
)
import qualified "base" Prelude as P hiding (fail)

-- | Boolean algebra of functions.
instance Boolean b => Boolean (a -> b) where
true = const true
true = const true
false = const false
not f = not . f
(&&) = liftA2 (&&)
(||) = liftA2 (||)
xor = liftA2 xor
(-->) = liftA2 (-->)
(&&) = liftA2 (&&)
(||) = liftA2 (||)
xor = liftA2 xor
(-->) = liftA2 (-->)
(<-->) = liftA2 (<-->)

instance FromJSValue Text where
Expand All @@ -112,6 +186,7 @@ instance ToJSValue Text where
-- Additional optics utilities.

{-# ANN copy ("HLint: ignore Eta reduce" :: String) #-}

-- | Copy the field value from an object of the same type.
copy :: (Is k A_Setter, Is k A_Getter) => Optic k is s s a a -> s -> s -> s
copy x fromThis toThat = set x (view x fromThis) toThat
Expand All @@ -126,11 +201,11 @@ for = flip map
maybeRead :: Read a => Text -> Maybe a
maybeRead s = case reads (T.unpack s) of
[(v, "")] -> Just v
_ -> Nothing
_ -> Nothing

-- | Returns Just if the precondition is true.
toMaybe :: Bool -> a -> Maybe a
toMaybe True x = Just x
toMaybe True x = Just x
toMaybe False _ = Nothing

----------------------------------------
Expand All @@ -143,14 +218,15 @@ identity = P.id
(!!) :: HasCallStack => [a] -> Int -> a
xs !! n
| n < 0 = negativeIndexError "!!"
| otherwise = foldr
(\x r k -> case k of
0 -> x
_ -> r (k - 1)
)
(indexOutOfBoundsError "!!")
xs
n
| otherwise =
foldr
( \x r k -> case k of
0 -> x
_ -> r (k - 1)
)
(indexOutOfBoundsError "!!")
xs
n

-- | Replacement for 'P.head' that provides useful information on failure.
head :: HasCallStack => [a] -> a
Expand All @@ -177,22 +253,22 @@ read :: (HasCallStack, Read a, Show a) => Text -> a
read s =
let parsedS = reads $ T.unpack s
in fromMaybe
( unexpectedError
$ "reading failed (input was '"
<> s
<> "', reads returned '"
<> showt parsedS
<> "')"
)
( unexpectedError $
"reading failed (input was '"
<> s
<> "', reads returned '"
<> showt parsedS
<> "')"
)
$ do
[(v, "")] <- return parsedS
return v
[(v, "")] <- return parsedS
return v

-- | General version of 'fromJust' with a custom error message
expectJust :: HasCallStack => Text -> Maybe a -> a
expectJust msg = \case
Nothing -> unexpectedError msg
Just a -> a
Just a -> a

-- | Replacement for 'Data.Maybe.fromJust' that provides useful
-- information on failure.
Expand All @@ -202,7 +278,7 @@ fromJust = expectJust "fromJust received Nothing"
-- | whenNothing mA fa = maybe fa return mA
whenNothing :: Applicative f => Maybe a -> f a -> f a
whenNothing (Just x) _ = pure x
whenNothing Nothing m = m
whenNothing Nothing m = m

-- | Like 'error', but with a more conspicous name.
unexpectedError :: HasCallStack => Text -> a
Expand Down Expand Up @@ -231,8 +307,11 @@ showt = T.pack . show

-- | Pretty print anything with a `Show` instance.
showtp :: Show a => a -> T.Text
showtp = TL.toStrict . pShowOpt
(defaultOutputOptionsDarkBg { outputOptionsCompact = True
, outputOptionsPageWidth = 180
}
)
showtp =
TL.toStrict
. pShowOpt
( defaultOutputOptionsDarkBg
{ outputOptionsCompact = True
, outputOptionsPageWidth = 180
}
)