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

Introduce purs-tidy formatter #138

Merged
merged 3 commits into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from all 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: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:

- name: Set up a PureScript toolchain
uses: purescript-contrib/setup-purescript@main
with:
purs-tidy: "latest"

- name: Cache PureScript dependencies
uses: actions/cache@v2
Expand All @@ -32,3 +34,6 @@ jobs:

- name: Run tests
run: spago test --no-install

- name: Check formatting
run: purs-tidy check src test examples
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
!.gitignore
!.github
!.editorconfig
!.tidyrc.json

output
generated-docs
Expand Down
10 changes: 10 additions & 0 deletions .tidyrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"importSort": "source",
"importWrap": "source",
"indent": 2,
"operatorsFile": null,
"ribbon": 1,
"typeArrowPlacement": "first",
"unicode": "never",
"width": null
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ New features:
Bugfixes:

Other improvements:
- Added `purs-tidy` formatter (#138 by @thomashoneyman)
- Replace manual tests with automated tests using `assert` (#135 by @neppord)
- Improve documentation for `united` (#134 by @neppord)
- Add guide on impredicativity explaining difference between `Lens` vs `ALens` (#136 by @i-am-tom and @JordanMartinez)
Expand Down
93 changes: 52 additions & 41 deletions examples/src/PrismsForSumTypes.purs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,17 @@ See `README.md` if you're wondering why code is formatted the way it is.
-}

import Prelude
import Data.Lens (Prism', is, isn't, nearly, only, preview, prism, prism', review)

import Color (Color)
import Color as Color

import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq as GEq
import Data.Generic.Rep.Show as GShow
import Data.Lens (Prism', is, isn't, nearly, only, preview, prism, prism', review)
import Data.Maybe (Maybe(..), maybe)
import Data.Either (Either(..))


{- The types in question -}
{- The types in question -}

newtype Percent = Percent Number
data Point = Point Number Number
Expand All @@ -51,7 +49,7 @@ data Fill -- think of a paint program filling a shape
| RadialGradient Color Color Point
| NoFill

{------ Some samples to work with ------}
{------ Some samples to work with ------}

fillBlackToWhite :: Fill
fillBlackToWhite = LinearGradient Color.black Color.white $ Percent 3.3
Expand All @@ -62,8 +60,7 @@ fillWhiteToBlack = LinearGradient Color.white Color.black $ Percent 3.3
fillRadial :: Fill
fillRadial = RadialGradient Color.white Color.black $ Point 1.0 3.4


{------ Making prisms with Maybe and `prism'` ------}
{------ Making prisms with Maybe and `prism'` ------}

-- `prism'` (note the apostrophe) takes two functions. One is a data
-- constructor for the type in question. The other converts your
Expand All @@ -72,10 +69,10 @@ fillRadial = RadialGradient Color.white Color.black $ Point 1.0 3.4
solidFocus :: Prism' Fill Color
solidFocus = prism' constructor focus
where
constructor = Solid
focus fill = case fill of
Solid color -> Just color
otherCases -> Nothing
constructor = Solid
focus fill = case fill of
Solid color -> Just color
otherCases -> Nothing

-- In real life, you might abbreviate the above to this:

Expand All @@ -86,37 +83,40 @@ solidFocus' = prism' Solid case _ of

-- ... but being painfully explicit is better for examples.


{------ Basic usage: `preview`, `review`, `is`, and `isn't` ------}
{------ Basic usage: `preview`, `review`, `is`, and `isn't` ------}

-- After building a prism, you focus in on a color with `preview`:

s1 :: Maybe Color
s1 = preview solidFocus (Solid Color.white)

-- (Just rgba 255 255 255 1.0)

s2 :: Maybe Color
s2 = preview solidFocus fillRadial

-- Nothing

-- ... or you can create a Fill from a color with `review`:

s3 :: Fill
s3 = review solidFocus Color.white

-- (Solid rgba 255 255 255 1.0)

-- ... or you can ask whether a given value matches the prism:

s4 :: Boolean
s4 = is solidFocus (Solid Color.white) :: Boolean

-- true

s5 :: Boolean
s5 = isn't solidFocus (Solid Color.white) :: Boolean
-- false

-- false

{------ Making prisms with Either and `prism` ------}
{------ Making prisms with Either and `prism` ------}

-- Since `LinearGradient` wraps two colors and a percent, they need to
-- be bundled together into a single value for `preview` to
Expand All @@ -135,50 +135,53 @@ type LinearInterchange =
linearFocus :: Prism' Fill LinearInterchange
linearFocus = prism constructor focus
where
constructor {color1, color2, percent} =
LinearGradient color1 color2 percent
focus = case _ of
LinearGradient color1 color2 percent ->
Right {color1, color2, percent}
otherCases ->
Left otherCases
constructor { color1, color2, percent } =
LinearGradient color1 color2 percent
focus = case _ of
LinearGradient color1 color2 percent ->
Right { color1, color2, percent }
otherCases ->
Left otherCases

-- Even though made differently than `solidFocus`, `linearFocus` is
-- used the same way:

l1 :: String
l1 = preview linearFocus fillBlackToWhite # maybe "!" show

-- "{ color1: rgba 0 0 0 1.0, color2: rgba 255 255 255 1.0, percent: (3.3%) }"

l2 :: Fill
l2 = review linearFocus { color1 : Color.black
, color2 : Color.white
, percent : Percent 33.3
}

l2 = review linearFocus
{ color1: Color.black
, color2: Color.white
, percent: Percent 33.3
}

{------ Use `only` to focus on specific values ------}
{------ Use `only` to focus on specific values ------}

whiteToBlackFocus :: Prism' Fill Unit
whiteToBlackFocus = only fillWhiteToBlack

o1 :: Boolean
o1 = is whiteToBlackFocus fillWhiteToBlack :: Boolean

-- true

o2 :: Boolean
o2 = is whiteToBlackFocus fillBlackToWhite :: Boolean

-- false

o3 :: Boolean
o3 = is whiteToBlackFocus fillRadial :: Boolean

-- false

-- Note that `only` requires `Fill` to implement `Eq`.
-- It's the only prism constructor that does.

{------ Use `nearly` to focus on a sub-case ------}

{------ Use `nearly` to focus on a sub-case ------}

-- `nearly` is typically used to look for a specific case (like other
-- prisms), but also accepts only values that are close to some target
Expand All @@ -193,61 +196,69 @@ o3 = is whiteToBlackFocus fillRadial :: Boolean
brightSolidFocus :: Prism' Fill Unit
brightSolidFocus = nearly (Solid referenceColor) predicate
where
referenceColor = Color.graytone 0.8
predicate = case _ of
Solid color ->
Color.brightness color >= Color.brightness referenceColor
_ ->
false
referenceColor = Color.graytone 0.8
predicate = case _ of
Solid color ->
Color.brightness color >= Color.brightness referenceColor
_ ->
false

-- Because a `nearly` prism focuses into `Unit`, you can get only two
-- values from `preview`:

n1 :: Maybe Unit
n1 = preview brightSolidFocus (Solid Color.white)

-- (Just unit)

n2 :: Maybe Unit
n2 = preview brightSolidFocus (Solid Color.black)

-- Nothing

n3 :: Maybe Unit
n3 = preview brightSolidFocus NoFill
-- Nothing

-- Nothing

-- ... so you probably want to use `is` or `isn't`:

n4 :: Boolean
n4 = is brightSolidFocus (Solid Color.white) :: Boolean

-- true

-- You can recover the reference value with `review`:

n5 :: Fill
n5 = review brightSolidFocus unit
-- (Solid rgba 204 204 204 1.0)


-- (Solid rgba 204 204 204 1.0)

{------ Eq and Show are always nice ------}
{------ Eq and Show are always nice ------}

-- ... although Eq is only required for `only`.

derive instance genericPercent :: Generic Percent _

instance eqPercent :: Eq Percent where
eq = GEq.genericEq

instance showPercent :: Show Percent where
show (Percent f) = "(" <> show f <> "%)"

derive instance genericPoint :: Generic Point _

instance eqPoint :: Eq Point where
eq = GEq.genericEq

instance showPoint :: Show Point where
show (Point x y) = "(" <> show x <> ", " <> show y <> ")"

derive instance genericFill :: Generic Fill _

instance eqFill :: Eq Fill where
eq = GEq.genericEq

instance showFill :: Show Fill where
show x = GShow.genericShow x
2 changes: 1 addition & 1 deletion packages.dhall
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.14.3-20210722/packages.dhall sha256:1ceb43aa59436bf5601bac45f6f3781c4e1f0e4c2b8458105b018e5ed8c30f8c
https://github.com/purescript/package-sets/releases/download/psc-0.14.5-20211116/packages.dhall sha256:7ba810597a275e43c83411d2ab0d4b3c54d0b551436f4b1632e9ff3eb62e327a

in upstream
16 changes: 8 additions & 8 deletions src/Data/Lens.purs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ module Data.Lens
, module Data.Lens.Common
) where

import Data.Lens.Iso (AnIso, AnIso', Iso, Iso', Optic, Exchange(..), Re(..), au, auf, cloneIso, non, curried, flipped, iso, re, uncurried, under, withIso)
import Data.Lens.Grate (Grate, Grate', zipWithOf, zipFWithOf, collectOf)
import Data.Lens.Lens (ALens, ALens', Lens, Lens', cloneLens, lens, lens', withLens, lensStore)
import Data.Lens.Common (_1, _2, _Just, _Left, _Nothing, _Right, first, left, right, second, united)
import Data.Lens.Fold (Fold, Fold', allOf, andOf, anyOf, elemOf, filtered, findOf, firstOf, foldMapOf, foldOf, folded, foldlOf, foldrOf, has, hasn't, iallOf, ianyOf, ifoldMapOf, ifoldlOf, ifoldrOf, itoListOf, itraverseOf_, lastOf, lengthOf, maximumOf, minimumOf, notElemOf, orOf, preview, previewOn, productOf, replicated, sequenceOf_, sumOf, toArrayOf, toArrayOfOn, toListOf, toListOfOn, unfolded, (^..), (^?))
import Data.Lens.Getter (Fold, Getter, Indexed(..), IndexedFold, IndexedGetter, Optic, cloneGetter, iuse, iview, takeBoth, to, use, view, viewOn, (^.))
import Data.Lens.Grate (Grate, Grate', collectOf, zipFWithOf, zipWithOf)
import Data.Lens.Iso (AnIso, AnIso', Exchange(..), Iso, Iso', Optic, Re(..), au, auf, cloneIso, curried, flipped, iso, non, re, uncurried, under, withIso)
import Data.Lens.Lens (ALens, ALens', Lens, Lens', cloneLens, lens, lens', lensStore, withLens)
import Data.Lens.Prism (APrism, APrism', Prism, Prism', Review, Review', clonePrism, is, isn't, matching, nearly, only, prism, prism', review, withPrism)
import Data.Lens.Setter (Indexed(..), IndexedSetter, Setter, Setter', addModifying, addOver, appendModifying, appendOver, assign, assignJust, conjModifying, conjOver, disjModifying, disjOver, divModifying, divOver, iover, modifying, mulModifying, mulOver, over, set, setJust, subModifying, subOver, (%=), (%~), (&&=), (&&~), (*=), (*~), (+=), (+~), (-=), (-~), (.=), (.~), (//=), (//~), (<>=), (<>~), (?=), (?~), (||=), (||~))
import Data.Lens.Traversal (Traversal, Traversal', element, elementsOf, failover, itraverseOf, sequenceOf, traverseOf, traversed)
import Data.Lens.Types (class Wander, ALens, ALens', APrism, APrism', AnIso, AnIso', ATraversal, ATraversal', Fold, Fold', Getter, Getter', AGetter, AGetter', IndexedFold, IndexedFold', IndexedGetter, IndexedGetter', IndexedOptic, IndexedOptic', IndexedSetter, IndexedSetter', IndexedTraversal, IndexedTraversal', Iso, Iso', Lens, Lens', Optic, Optic', Prism, Prism', Review, Review', Setter, Setter', Traversal, Traversal', Exchange(..), Forget(..), Indexed(..), Market(..), Re(..), Shop(..), Tagged(..), wander)
import Data.Lens.Setter (IndexedSetter, Setter, Setter', Indexed(..), addModifying, addOver, appendModifying, appendOver, assign, assignJust, conjModifying, conjOver, disjModifying, disjOver, divModifying, divOver, iover, modifying, mulModifying, mulOver, over, set, setJust, subModifying, subOver, (%=), (%~), (&&=), (&&~), (*=), (*~), (+=), (+~), (-=), (-~), (.=), (.~), (//=), (//~), (<>=), (<>~), (?=), (?~), (||=), (||~))
import Data.Lens.Getter (Fold, Getter, IndexedFold, IndexedGetter, Optic, Indexed(..), iuse, iview, to, takeBoth, use, view, viewOn, (^.), cloneGetter)
import Data.Lens.Fold (Fold, Fold', allOf, andOf, anyOf, elemOf, filtered, findOf, firstOf, foldMapOf, foldOf, folded, foldlOf, foldrOf, has, hasn't, iallOf, ianyOf, ifoldMapOf, ifoldlOf, ifoldrOf, itoListOf, itraverseOf_, lastOf, lengthOf, maximumOf, minimumOf, notElemOf, orOf, preview, previewOn, productOf, replicated, sequenceOf_, sumOf, toArrayOf, toArrayOfOn, toListOf, toListOfOn, unfolded, (^..), (^?))
import Data.Lens.Common (_1, _2, _Just, _Left, _Nothing, _Right, first, left, right, second, united)
import Data.Lens.Types (class Wander, AGetter, AGetter', ALens, ALens', APrism, APrism', ATraversal, ATraversal', AnIso, AnIso', Exchange(..), Fold, Fold', Forget(..), Getter, Getter', Indexed(..), IndexedFold, IndexedFold', IndexedGetter, IndexedGetter', IndexedOptic, IndexedOptic', IndexedSetter, IndexedSetter', IndexedTraversal, IndexedTraversal', Iso, Iso', Lens, Lens', Market(..), Optic, Optic', Prism, Prism', Re(..), Review, Review', Setter, Setter', Shop(..), Tagged(..), Traversal, Traversal', wander)
36 changes: 18 additions & 18 deletions src/Data/Lens/AffineTraversal.purs
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,33 @@ import Data.Profunctor.Choice (right)
import Data.Profunctor.Strong (second, (&&&))
import Data.Tuple (Tuple(..))

affineTraversal ::
forall s t a b .
(s -> b -> t) ->
(s -> Either t a) ->
AffineTraversal s t a b
affineTraversal
:: forall s t a b
. (s -> b -> t)
-> (s -> Either t a)
-> AffineTraversal s t a b
affineTraversal set pre =
affineTraversal' (set &&& pre)

affineTraversal' ::
forall s t a b .
(s -> Tuple (b -> t) (Either t a)) ->
AffineTraversal s t a b
affineTraversal'
:: forall s t a b
. (s -> Tuple (b -> t) (Either t a))
-> AffineTraversal s t a b
affineTraversal' to pab =
dimap to (\(Tuple b f) -> either identity b f) (second (right pab))

withAffineTraversal ::
forall s t a b r .
AnAffineTraversal s t a b ->
((s -> b -> t) -> (s -> Either t a) -> r) ->
r
withAffineTraversal
:: forall s t a b r
. AnAffineTraversal s t a b
-> ((s -> b -> t) -> (s -> Either t a) -> r)
-> r
withAffineTraversal l f = case l (Stall (const identity) Right) of
Stall g h -> f g h

cloneAffineTraversal ::
forall s t a b .
AnAffineTraversal s t a b ->
AffineTraversal s t a b
cloneAffineTraversal
:: forall s t a b
. AnAffineTraversal s t a b
-> AffineTraversal s t a b
cloneAffineTraversal l =
withAffineTraversal l \x y p ->
affineTraversal x y p
12 changes: 5 additions & 7 deletions src/Data/Lens/At.purs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module Data.Lens.At
, sans
) where


import Prelude

import Data.Identity (Identity(..))
Expand Down Expand Up @@ -45,12 +44,11 @@ instance atMaybe :: At (Maybe a) Unit a where
instance atSet :: Ord v => At (S.Set v) v Unit where
at x = lens get (flip update)
where
get xs =
if S.member x xs
then Just unit
else Nothing
update Nothing = S.delete x
update (Just _) = S.insert x
get xs =
if S.member x xs then Just unit
else Nothing
update Nothing = S.delete x
update (Just _) = S.insert x

instance atMap :: Ord k => At (M.Map k v) k v where
at k =
Expand Down
Loading