smash-lens 0.1.0.3 → 0.2.0
raw patch · 9 files changed
+142/−26 lines, 9 filesdep +QuickCheckdep +smash-lensdep +tastydep ~basedep ~lensdep ~smashPVP ok
version bump matches the API change (PVP)
Dependencies added: QuickCheck, smash-lens, tasty, tasty-hunit, tasty-quickcheck
Dependency ranges changed: base, lens, smash
API changes (from Hackage documentation)
- Data.Can.Lens: _CanIso :: Iso (Can a b) (Can c d) (Maybe a, Maybe b) (Maybe c, Maybe d)
+ Data.Can.Lens: _CanIso :: forall a b c d p f. (Profunctor p, Functor f) => p (Maybe a, Maybe b) (f (Maybe c, Maybe d)) -> p (Can a b) (f (Can c d))
- Data.Can.Lens: _Eno :: Prism' (Can a b) b
+ Data.Can.Lens: _Eno :: forall a b p f. (Choice p, Applicative f) => p b (f b) -> p (Can a b) (f (Can a b))
- Data.Can.Lens: _Non :: Prism' (Can a b) ()
+ Data.Can.Lens: _Non :: forall a b p f. (Choice p, Applicative f) => p () (f ()) -> p (Can a b) (f (Can a b))
- Data.Can.Lens: _One :: Prism' (Can a b) a
+ Data.Can.Lens: _One :: forall a b p f. (Choice p, Applicative f) => p a (f a) -> p (Can a b) (f (Can a b))
- Data.Can.Lens: _Two :: Prism' (Can a b) (a, b)
+ Data.Can.Lens: _Two :: forall a b p f. (Choice p, Applicative f) => p (a, b) (f (a, b)) -> p (Can a b) (f (Can a b))
- Data.Can.Lens: enoing :: Traversal (Can a b) (Can a c) b c
+ Data.Can.Lens: enoing :: forall a b c f. Applicative f => (b -> f c) -> Can a b -> f (Can a c)
- Data.Can.Lens: oneing :: Traversal (Can a c) (Can b c) a b
+ Data.Can.Lens: oneing :: forall a c b f. Applicative f => (a -> f b) -> Can a c -> f (Can b c)
- Data.Can.Lens: twoed :: Traversal' (Can a b) (a, b)
+ Data.Can.Lens: twoed :: forall a b f. Applicative f => ((a, b) -> f (a, b)) -> Can a b -> f (Can a b)
- Data.Can.Lens: twoing :: Traversal (Can a a) (Can b b) a b
+ Data.Can.Lens: twoing :: forall a b f. Applicative f => (a -> f b) -> Can a a -> f (Can b b)
- Data.Smash.Lens: _Nada :: Prism' (Smash a b) ()
+ Data.Smash.Lens: _Nada :: forall a b p f. (Choice p, Applicative f) => p () (f ()) -> p (Smash a b) (f (Smash a b))
- Data.Smash.Lens: _Smash :: Prism' (Smash a b) (a, b)
+ Data.Smash.Lens: _Smash :: forall a b p f. (Choice p, Applicative f) => p (a, b) (f (a, b)) -> p (Smash a b) (f (Smash a b))
- Data.Smash.Lens: _SmashIso :: Iso (Smash a b) (Smash c d) (Maybe (a, b)) (Maybe (c, d))
+ Data.Smash.Lens: _SmashIso :: forall a b c d p f. (Profunctor p, Functor f) => p (Maybe (a, b)) (f (Maybe (c, d))) -> p (Smash a b) (f (Smash c d))
- Data.Smash.Lens: smashed :: Traversal (Smash a b) (Smash c d) (a, b) (c, d)
+ Data.Smash.Lens: smashed :: forall a b c d f. Applicative f => ((a, b) -> f (c, d)) -> Smash a b -> f (Smash c d)
- Data.Smash.Lens: smashing :: Traversal (Smash a a) (Smash b b) a b
+ Data.Smash.Lens: smashing :: forall a b f. Applicative f => (a -> f b) -> Smash a a -> f (Smash b b)
- Data.Wedge.Lens: _Here :: Prism (Wedge a b) (Wedge c b) a c
+ Data.Wedge.Lens: _Here :: forall a b c p f. (Choice p, Applicative f) => p a (f c) -> p (Wedge a b) (f (Wedge c b))
- Data.Wedge.Lens: _Nowhere :: Prism' (Wedge a b) ()
+ Data.Wedge.Lens: _Nowhere :: forall a b p f. (Choice p, Applicative f) => p () (f ()) -> p (Wedge a b) (f (Wedge a b))
- Data.Wedge.Lens: _There :: Prism (Wedge a b) (Wedge a d) b d
+ Data.Wedge.Lens: _There :: forall a b d p f. (Choice p, Applicative f) => p b (f d) -> p (Wedge a b) (f (Wedge a d))
- Data.Wedge.Lens: _WedgeIso :: Iso (Wedge a b) (Wedge c d) (Maybe (Either a b)) (Maybe (Either c d))
+ Data.Wedge.Lens: _WedgeIso :: forall a b c d p f. (Profunctor p, Functor f) => p (Maybe (Either a b)) (f (Maybe (Either c d))) -> p (Wedge a b) (f (Wedge c d))
- Data.Wedge.Lens: here :: Traversal' (Wedge a b) a
+ Data.Wedge.Lens: here :: forall a b f. Applicative f => (a -> f a) -> Wedge a b -> f (Wedge a b)
- Data.Wedge.Lens: there :: Traversal' (Wedge a b) b
+ Data.Wedge.Lens: there :: forall a b f. Applicative f => (b -> f b) -> Wedge a b -> f (Wedge a b)
Files
- CHANGELOG.md +11/−0
- LICENSE +1/−1
- README.md +1/−1
- smash-lens.cabal +26/−17
- src/Data/Can/Lens.hs +2/−1
- src/Data/Smash/Lens.hs +2/−1
- src/Data/Wedge/Lens.hs +3/−1
- test/Main.hs +96/−0
- test/MyLibTest.hs +0/−4
CHANGELOG.md view
@@ -1,5 +1,16 @@ # Revision history for smash-lens +## 0.2.0 -- 2026-10-26++* Start the `0.2` major release series and require `smash >=0.2.0 && <0.3`.+* Preserve the existing optics API and traversal behavior.++## 0.1.0.4 -- 2026-10-26++* Update dependency bounds and the supported GHC matrix to 9.6–9.14.+* Update copyrights through 2026.+* Add Tasty unit and property tests for constructor selection and traversal laws.+ ## 0.1.0.3 -- 2022-04-03 * Update `base` bounds to allow GHC 9.2.x
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2020, Emily Pillmore+Copyright (c) 2020-2026, Emily Pillmore All rights reserved.
README.md view
@@ -1,7 +1,7 @@ # smash-lens: Optics for the smash library -[](https://travis-ci.com/emilypi/smash)+[](https://github.com/emilypi/smash/actions/workflows/haskell-ci.yml) [](https://hackage.haskell.org/package/smash-lens)
smash-lens.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: smash-lens-version: 0.1.0.3+version: 0.2.0 synopsis: Optics for the `smash` library description: Prisms, Traversals, and combinators for the `smash` library.@@ -11,19 +11,19 @@ license-file: LICENSE author: Emily Pillmore maintainer: emilypi@cohomolo.gy-copyright: (c) 2020-2022 Emily Pillmore <emilypi@cohomolo.gy>+copyright: (c) 2020-2026 Emily Pillmore <emilypi@cohomolo.gy> category: Data build-type: Simple-extra-source-files:+extra-doc-files: CHANGELOG.md README.md tested-with:- GHC ==8.6.5- || ==8.8.4- || ==8.10.7- || ==9.0.2- || ==9.2.2+ GHC ==9.6.7+ || ==9.8.4+ || ==9.10.3+ || ==9.12.4+ || ==9.14.1 source-repository head type: git@@ -35,20 +35,29 @@ Data.Smash.Lens Data.Wedge.Lens - -- other-modules:- -- other-extensions: build-depends:- base >=4.11 && <4.17- , lens >=4.0 && <5.2- , smash >=0.1.3+ base >=4.15 && <4.23+ , lens >=4.0 && <5.4+ , smash >=0.2.0 && <0.3 hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall -test-suite smash-lens-test++test-suite smash-lens-tests default-language: Haskell2010 type: exitcode-stdio-1.0- hs-source-dirs: test- main-is: MyLibTest.hs- build-depends: base >=4.10 && <5.0+ hs-source-dirs: test+ main-is: Main.hs+ build-depends:+ base >=4.15 && <4.23+ , smash-lens+ , tasty >=1.4 && <1.6+ , tasty-hunit >=0.10 && <0.11+ , tasty-quickcheck >=0.10 && <0.12+ , QuickCheck >=2.14 && <2.17+ , smash >=0.2.0 && <0.3+ , lens++ ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
src/Data/Can/Lens.hs view
@@ -4,10 +4,11 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeOperators #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module : Data.Can.Lens--- Copyright : (c) 2020-2022 Emily Pillmore+-- Copyright : (c) 2020-2026 Emily Pillmore -- License : BSD-style -- -- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>
src/Data/Smash/Lens.hs view
@@ -4,10 +4,11 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeOperators #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module : Data.Smash.Lens--- Copyright : (c) 2020-2022 Emily Pillmore+-- Copyright : (c) 2020-2026 Emily Pillmore -- License : BSD-style -- -- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>
src/Data/Wedge/Lens.hs view
@@ -4,10 +4,12 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeOperators #-}+ {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module : Data.Wedge.Lens--- Copyright : (c) 2020-2022 Emily Pillmore+-- Copyright : (c) 2020-2026 Emily Pillmore -- License : BSD-style -- -- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>
+ test/Main.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE ScopedTypeVariables #-}+-- Copyright (c) 2020-2026 Emily Pillmore+module Main (main) where++import Data.Bifunctor (bimap)+import Data.Can+import Data.Can.Lens+import Data.Smash+import Data.Smash.Lens+import Data.Wedge+import Data.Wedge.Lens+import Control.Lens hiding (bimap)+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck++main :: IO ()+main = defaultMain $ testGroup "smash-lens"+ [ testGroup "Constructor selection"+ [ testCase "Can constructors select only their exact branch" $ do+ map (\x -> x ^? _Non) cs @?= [Just (), Nothing, Nothing, Nothing]+ map (\x -> x ^? _One) cs @?= [Nothing, Just 1, Nothing, Nothing]+ map (\x -> x ^? _Eno) cs @?= [Nothing, Nothing, Just 2, Nothing]+ map (\x -> x ^? _Two) cs @?= [Nothing, Nothing, Nothing, Just (1,2)]+ , testCase "Smash constructors select only their exact branch" $ do+ map (\x -> x ^? _Nada) ss @?= [Just (), Nothing]+ map (\x -> x ^? _Smash) ss @?= [Nothing, Just (1,2)]+ , testCase "Wedge constructors select only their exact branch" $ do+ map (\x -> x ^? _Nowhere) ws @?= [Just (), Nothing, Nothing]+ map (\x -> x ^? _Here) ws @?= [Nothing, Just 1, Nothing]+ map (\x -> x ^? _There) ws @?= [Nothing, Nothing, Just 2]+ , testCase "pair traversals preserve unmatched branches" $ do+ map (over twoed (\(a,b) -> (a+10,b+20))) cs @?= [Non, One 1, Eno 2, Two 11 22]+ map (over smashed (\(a,b) -> (a+10,b+20))) ss @?= [Nada, Smash 11 22]+ , testCase "type-changing traversals preserve the other payload" $ do+ over oneing show (Two (1 :: Int) True) @?= Two "1" True+ over enoing show (Two True (2 :: Int)) @?= Two True "2"+ over _Here show (Here (1 :: Int) :: Wedge Int Bool) @?= Here "1"+ over _There show (There (2 :: Int) :: Wedge Bool Int) @?= There "2"+ ]+ , testGroup "Traversal properties"+ [ testProperty "Can left traversal agrees with bimap" $ \a b (Fun _ f :: Fun Int Int) ->+ conjoin [over oneing f x === bimap f id x | x <- canValues a b]+ , testProperty "Can right traversal agrees with bimap" $ \a b (Fun _ f :: Fun Int Int) ->+ conjoin [over enoing f x === bimap id f x | x <- canValues a b]+ , testProperty "Can both traversal agrees with bimap" $ \a b (Fun _ f :: Fun Int Int) ->+ conjoin [over twoing f x === bimap f f x | x <- canValues a b]+ , testProperty "Smash traversal agrees with bimap" $ \a b (Fun _ f :: Fun Int Int) ->+ conjoin [over smashing f x === bimap f f x | x <- smashValues a b]+ , testProperty "Wedge traversals agree with bimap" $ \a b (Fun _ f :: Fun Int Int) ->+ conjoin [over here f x === bimap f id x .&&. over there f x === bimap id f x | x <- wedgeValues a b]+ , testProperty "Can traversal identity" $ \a b ->+ conjoin [over twoing id x === x | x <- canValues a b]+ , testProperty "Smash traversal identity" $ \a b ->+ conjoin [over smashing id x === x | x <- smashValues a b]+ , testProperty "Wedge traversal identity" $ \a b ->+ conjoin [over here id x === x .&&. over there id x === x | x <- wedgeValues a b]+ , testProperty "Can traversal composition" $ \a b (Fun _ f :: Fun Int Int) (Fun _ g :: Fun Int Int) ->+ conjoin [over twoing f (over twoing g x) === over twoing (f . g) x | x <- canValues a b]+ , testProperty "Smash traversal composition" $ \a b (Fun _ f :: Fun Int Int) (Fun _ g :: Fun Int Int) ->+ conjoin [over smashing f (over smashing g x) === over smashing (f . g) x | x <- smashValues a b]+ , testProperty "Wedge traversal composition" $ \a b (Fun _ f :: Fun Int Int) (Fun _ g :: Fun Int Int) ->+ conjoin [over here f (over here g x) === over here (f . g) x .&&.+ over there f (over there g x) === over there (f . g) x | x <- wedgeValues a b]+ ]+ , testGroup "Isomorphisms and prisms"+ [ testProperty "Can iso agrees with projections and roundtrips" $ \a b ->+ conjoin [view _CanIso x === (canFst x, canSnd x) .&&. review _CanIso (view _CanIso x) === x | x <- canValues a b]+ , testProperty "Smash iso agrees with conversion and roundtrips" $ \a b ->+ conjoin [view _SmashIso x === fromSmash x .&&. review _SmashIso (view _SmashIso x) === x | x <- smashValues a b]+ , testProperty "Wedge iso agrees with conversion and roundtrips" $ \a b ->+ conjoin [view _WedgeIso x === fromWedge x .&&. review _WedgeIso (view _WedgeIso x) === x | x <- wedgeValues a b]+ , testProperty "constructor prism review/preview roundtrips" $ \(a :: Int) (b :: Int) -> conjoin+ [ ((review _One a :: Can Int Int) ^? _One) === Just a+ , ((review _Eno b :: Can Int Int) ^? _Eno) === Just b+ , ((review _Two (a,b) :: Can Int Int) ^? _Two) === Just (a,b)+ , ((review _Smash (a,b) :: Smash Int Int) ^? _Smash) === Just (a,b)+ , ((review _Here a :: Wedge Int Int) ^? _Here) === Just a+ , ((review _There b :: Wedge Int Int) ^? _There) === Just b+ ]+ ]++ ]+ where+ cs = canValues 1 2+ ss = smashValues 1 2+ ws = wedgeValues 1 2++canValues :: Int -> Int -> [Can Int Int]+canValues a b = [Non, One a, Eno b, Two a b]++smashValues :: Int -> Int -> [Smash Int Int]+smashValues a b = [Nada, Smash a b]++wedgeValues :: Int -> Int -> [Wedge Int Int]+wedgeValues a b = [Nowhere, Here a, There b]
− test/MyLibTest.hs
@@ -1,4 +0,0 @@-module Main (main) where--main :: IO ()-main = putStrLn "Test suite not yet implemented."