{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

-- | Standard test `Spec`s for optics
module Test.Syd.Validity.Lens
  ( lensSpecOnValid,
    lensSpec,
    lensSpecOnArbitrary,
    lensSpecOnGen,
    lensLaw1,
    lensLaw2,
    lensLaw3,
    lensGettingProducesValidOnValid,
    lensGettingProducesValid,
    lensGettingProducesValidOnArbitrary,
    lensGettingProducesValidOnGen,
    lensSettingProducesValidOnValid,
    lensSettingProducesValid,
    lensSettingProducesValidOnArbitrary,
    lensSettingProducesValidOnGen,
  )
where

import Data.GenValidity
import Lens.Micro
import Lens.Micro.Extras
import Test.QuickCheck
import Test.Syd
import Test.Syd.Validity.Utils

-- | Standard test spec for properties lenses for valid values
--
-- Example usage:
--
-- > lensSpecOnValid ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational)
lensSpecOnValid ::
  forall s b.
  (Show b, Eq b, GenValid b, Show s, Eq s, GenValid s) =>
  Lens s s b b ->
  Spec
lensSpecOnValid :: Lens s s b b -> Spec
lensSpecOnValid Lens s s b b
l =
  Lens s s b b
-> Gen b
-> String
-> (b -> [b])
-> Gen s
-> String
-> (s -> [s])
-> Spec
forall b s.
(Show b, Eq b, Validity b, Show s, Eq s, Validity s) =>
Lens s s b b
-> Gen b
-> String
-> (b -> [b])
-> Gen s
-> String
-> (s -> [s])
-> Spec
lensSpecOnGen
    Lens s s b b
l
    (GenValid b => Gen b
forall a. GenValid a => Gen a
genValid @b)
    String
"valid values"
    b -> [b]
forall a. GenValid a => a -> [a]
shrinkValid
    (GenValid s => Gen s
forall a. GenValid a => Gen a
genValid @s)
    String
"valid values"
    s -> [s]
forall a. GenValid a => a -> [a]
shrinkValid

-- | Standard test spec for properties lenses for unchecked values
--
-- Example usage:
--
-- > lensSpec ((_2) :: Lens (Int, Int) (Int, Int) Int Int)
lensSpec ::
  forall s b.
  ( Show b,
    Eq b,
    GenUnchecked b,
    Validity b,
    Show s,
    Eq s,
    GenUnchecked s,
    Validity s
  ) =>
  Lens s s b b ->
  Spec
lensSpec :: Lens s s b b -> Spec
lensSpec Lens s s b b
l =
  Lens s s b b
-> Gen b
-> String
-> (b -> [b])
-> Gen s
-> String
-> (s -> [s])
-> Spec
forall b s.
(Show b, Eq b, Validity b, Show s, Eq s, Validity s) =>
Lens s s b b
-> Gen b
-> String
-> (b -> [b])
-> Gen s
-> String
-> (s -> [s])
-> Spec
lensSpecOnGen
    Lens s s b b
l
    (GenUnchecked b => Gen b
forall a. GenUnchecked a => Gen a
genUnchecked @b)
    String
"unchecked values"
    b -> [b]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked
    (GenUnchecked s => Gen s
forall a. GenUnchecked a => Gen a
genUnchecked @s)
    String
"unchecked values"
    s -> [s]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

-- | Standard test spec for properties lenses for arbitrary values
--
-- Example usage:
--
-- > lensSpecOnArbitrary ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational)
lensSpecOnArbitrary ::
  forall s b.
  ( Show b,
    Eq b,
    Arbitrary b,
    Validity b,
    Show s,
    Eq s,
    Arbitrary s,
    Validity s
  ) =>
  Lens s s b b ->
  Spec
lensSpecOnArbitrary :: Lens s s b b -> Spec
lensSpecOnArbitrary Lens s s b b
l =
  Lens s s b b
-> Gen b
-> String
-> (b -> [b])
-> Gen s
-> String
-> (s -> [s])
-> Spec
forall b s.
(Show b, Eq b, Validity b, Show s, Eq s, Validity s) =>
Lens s s b b
-> Gen b
-> String
-> (b -> [b])
-> Gen s
-> String
-> (s -> [s])
-> Spec
lensSpecOnGen
    Lens s s b b
l
    (Arbitrary b => Gen b
forall a. Arbitrary a => Gen a
arbitrary @b)
    String
"arbitrary values"
    b -> [b]
forall a. Arbitrary a => a -> [a]
shrink
    (Arbitrary s => Gen s
forall a. Arbitrary a => Gen a
arbitrary @s)
    String
"arbitrary values"
    s -> [s]
forall a. Arbitrary a => a -> [a]
shrink

-- | Standard test spec for properties lenses for values generated by given generators
--
-- Example usage:
--
-- > lensSpecOnGen
-- >      ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational)
-- >      (abs <$> genValid)
-- >      "positive valid doubles"
-- >      (filter (0.0 >=) . shrinkValid)
-- >      ((,) <$> (negate . abs <$> genValid) <*> (negate . abs <$> genValid))
-- >      "tuples of negative valid doubles"
-- >      (const [])
lensSpecOnGen ::
  (Show b, Eq b, Validity b, Show s, Eq s, Validity s) =>
  Lens s s b b ->
  Gen b ->
  String ->
  (b -> [b]) ->
  Gen s ->
  String ->
  (s -> [s]) ->
  Spec
lensSpecOnGen :: Lens s s b b
-> Gen b
-> String
-> (b -> [b])
-> Gen s
-> String
-> (s -> [s])
-> Spec
lensSpecOnGen Lens s s b b
l Gen b
genB String
genBName b -> [b]
shrinkB Gen s
genS String
genSName s -> [s]
shrinkS = do
  Spec -> Spec
forall (a :: [*]) b c. TestDefM a b c -> TestDefM a b c
parallel (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> Property -> Spec
forall (outers :: [*]) inner test.
(HasCallStack, IsTest test, Arg1 test ~ (), Arg2 test ~ inner) =>
String -> test -> TestDefM outers inner ()
it
      ( [String] -> String
unwords
          [String
"satisfies the first lens law for", String
genBName, String
"and", String
genSName]
      )
      (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Lens s s b b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
forall b s.
(Show b, Eq b, Show s) =>
Lens s s b b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensLaw1 Lens s s b b
l Gen b
genB b -> [b]
shrinkB Gen s
genS s -> [s]
shrinkS
    String -> Property -> Spec
forall (outers :: [*]) inner test.
(HasCallStack, IsTest test, Arg1 test ~ (), Arg2 test ~ inner) =>
String -> test -> TestDefM outers inner ()
it ([String] -> String
unwords [String
"satisfies the second lens law for", String
genSName]) (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Lens s s b b -> Gen s -> (s -> [s]) -> Property
forall s b.
(Show s, Eq s) =>
Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensLaw2 Lens s s b b
l Gen s
genS s -> [s]
shrinkS
    String -> Property -> Spec
forall (outers :: [*]) inner test.
(HasCallStack, IsTest test, Arg1 test ~ (), Arg2 test ~ inner) =>
String -> test -> TestDefM outers inner ()
it
      ( [String] -> String
unwords
          [String
"satisfies the third lens law for", String
genBName, String
"and", String
genSName]
      )
      (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Lens s s b b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
forall b s a.
(Show b, Show s, Eq s) =>
Lens s s a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensLaw3 Lens s s b b
l Gen b
genB b -> [b]
shrinkB Gen s
genS s -> [s]
shrinkS
    String -> Property -> Spec
forall (outers :: [*]) inner test.
(HasCallStack, IsTest test, Arg1 test ~ (), Arg2 test ~ inner) =>
String -> test -> TestDefM outers inner ()
it ([String] -> String
unwords [String
"gets valid values from", String
genSName, String
"values"]) (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Lens s s b b -> Gen s -> (s -> [s]) -> Property
forall b s.
(Validity b, Show b, Show s) =>
Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensGettingProducesValidOnGen Lens s s b b
l Gen s
genS s -> [s]
shrinkS
    String -> Property -> Spec
forall (outers :: [*]) inner test.
(HasCallStack, IsTest test, Arg1 test ~ (), Arg2 test ~ inner) =>
String -> test -> TestDefM outers inner ()
it
      ( [String] -> String
unwords
          [ String
"produces valid values when it is used to set",
            String
genBName,
            String
"values on",
            String
genSName,
            String
"values"
          ]
      )
      (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$ Lens s s b b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
forall s b t a.
(Show s, Show b, Show t, Validity t) =>
Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensSettingProducesValidOnGen Lens s s b b
l Gen b
genB b -> [b]
shrinkB Gen s
genS s -> [s]
shrinkS

-- | A property combinator for the first lens law:
--
-- > view l (set l v s)  ≡ v
--
-- Example usage:
--
-- prop> lensLaw1 ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational) genValid shrinkValid genValid shrinkValid
lensLaw1 ::
  (Show b, Eq b, Show s) =>
  Lens s s b b ->
  Gen b ->
  (b -> [b]) ->
  Gen s ->
  (s -> [s]) ->
  Property
lensLaw1 :: Lens s s b b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensLaw1 Lens s s b b
l Gen b
genB b -> [b]
shrinkB Gen s
genS s -> [s]
shrinkS =
  Gen b -> (b -> [b]) -> (b -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen b
genB b -> [b]
shrinkB ((b -> Property) -> Property) -> (b -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \b
b ->
    Gen s -> (s -> [s]) -> (s -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen s
genS s -> [s]
shrinkS ((s -> IO ()) -> Property) -> (s -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \s
s -> Getting b s b -> s -> b
forall a s. Getting a s a -> s -> a
view Getting b s b
Lens s s b b
l (ASetter s s b b -> b -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter s s b b
Lens s s b b
l b
b s
s) b -> b -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` b
b

-- | A property combinator for the second lens law:
--
-- > set l (view l s) s  ≡ s
--
-- Example usage:
--
-- prop> lensLaw2 ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational) genValid shrinkValid
lensLaw2 :: (Show s, Eq s) => Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensLaw2 :: Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensLaw2 Lens s s b b
l Gen s
genS s -> [s]
shrinkS =
  Gen s -> (s -> [s]) -> (s -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen s
genS s -> [s]
shrinkS ((s -> IO ()) -> Property) -> (s -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \s
s -> ASetter s s b b -> b -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter s s b b
Lens s s b b
l (Getting b s b -> s -> b
forall a s. Getting a s a -> s -> a
view Getting b s b
Lens s s b b
l s
s) s
s s -> s -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` s
s

-- | A property combinator for the third lens law:
--
-- > set l v' (set l v s) ≡ set l v' s
--
-- Example usage:
--
-- prop> lensLaw3 ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational) genValid shrinkValid genValid shrinkValid
lensLaw3 ::
  (Show b, Show s, Eq s) =>
  Lens s s a b ->
  Gen b ->
  (b -> [b]) ->
  Gen s ->
  (s -> [s]) ->
  Property
lensLaw3 :: Lens s s a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensLaw3 Lens s s a b
l Gen b
genB b -> [b]
shrinkB Gen s
genS s -> [s]
shrinkS =
  Gen b -> (b -> [b]) -> (b -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen b
genB b -> [b]
shrinkB ((b -> Property) -> Property) -> (b -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \b
b ->
    Gen b -> (b -> [b]) -> (b -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen b
genB b -> [b]
shrinkB ((b -> Property) -> Property) -> (b -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \b
b' ->
      Gen s -> (s -> [s]) -> (s -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen s
genS s -> [s]
shrinkS ((s -> IO ()) -> Property) -> (s -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \s
s ->
        ASetter s s a b -> b -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter s s a b
Lens s s a b
l b
b' (ASetter s s a b -> b -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter s s a b
Lens s s a b
l b
b s
s) s -> s -> IO ()
forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO ()
`shouldBe` ASetter s s a b -> b -> s -> s
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter s s a b
Lens s s a b
l b
b' s
s

-- | A property combinator to test whether getting values via a lens on valid values produces valid values.
--
-- Example Usage:
--
-- prop> lensGettingProducesValidOnValid ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational)
lensGettingProducesValidOnValid ::
  (Show s, GenValid s, Show b, GenValid b) => Lens s s b b -> Property
lensGettingProducesValidOnValid :: Lens s s b b -> Property
lensGettingProducesValidOnValid Lens s s b b
l =
  Lens s s b b -> Gen s -> (s -> [s]) -> Property
forall b s.
(Validity b, Show b, Show s) =>
Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensGettingProducesValidOnGen Lens s s b b
l Gen s
forall a. GenValid a => Gen a
genValid s -> [s]
forall a. GenValid a => a -> [a]
shrinkValid

-- | A property combinator to test whether getting values via a lens on unchecked values produces valid values.
--
-- Example Usage:
--
-- prop> lensGettingProducesValid ((_2) :: Lens (Int, Int) (Int, Int) Int Int)
lensGettingProducesValid ::
  (Show s, GenUnchecked s, Show b, Validity b) => Lens s s b b -> Property
lensGettingProducesValid :: Lens s s b b -> Property
lensGettingProducesValid Lens s s b b
l =
  Lens s s b b -> Gen s -> (s -> [s]) -> Property
forall b s.
(Validity b, Show b, Show s) =>
Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensGettingProducesValidOnGen Lens s s b b
l Gen s
forall a. GenUnchecked a => Gen a
genUnchecked s -> [s]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

-- | A property combinator to test whether getting values via a lens on arbitrary values produces valid values.
--
-- Example Usage:
--
-- prop> lensGettingProducesValidOnArbitrary ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational)
lensGettingProducesValidOnArbitrary ::
  (Show s, Arbitrary s, Show b, Validity b) =>
  Lens s s b b ->
  Property
lensGettingProducesValidOnArbitrary :: Lens s s b b -> Property
lensGettingProducesValidOnArbitrary Lens s s b b
l =
  Lens s s b b -> Gen s -> (s -> [s]) -> Property
forall b s.
(Validity b, Show b, Show s) =>
Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensGettingProducesValidOnGen Lens s s b b
l Gen s
forall a. Arbitrary a => Gen a
arbitrary s -> [s]
forall a. Arbitrary a => a -> [a]
shrink

-- | A property combinator to test whether getting values generated by given a generator via a lens on values generated by a given generator produces valid values.
--
-- > isValid (view l s)
--
-- Example Usage:
--
-- prop> lensGettingProducesValidOnGen ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational) genValid shrinkValid
lensGettingProducesValidOnGen ::
  (Validity b, Show b, Show s) =>
  Lens s s b b ->
  Gen s ->
  (s -> [s]) ->
  Property
lensGettingProducesValidOnGen :: Lens s s b b -> Gen s -> (s -> [s]) -> Property
lensGettingProducesValidOnGen Lens s s b b
l Gen s
genS s -> [s]
shrinkS =
  Gen s -> (s -> [s]) -> (s -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen s
genS s -> [s]
shrinkS ((s -> IO ()) -> Property) -> (s -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \s
s -> b -> IO ()
forall a. (Show a, Validity a) => a -> IO ()
shouldBeValid (b -> IO ()) -> b -> IO ()
forall a b. (a -> b) -> a -> b
$ Getting b s b -> s -> b
forall a s. Getting a s a -> s -> a
view Getting b s b
Lens s s b b
l s
s

-- | A property combinator to test whether setting valid values via a lens on valid values produces valid values.
--
-- Example usage:
--
-- prop> lensSettingProducesValidOnValid ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational)
lensSettingProducesValidOnValid ::
  (Show s, GenValid s, Show b, GenValid b, Show t, Validity t) =>
  Lens s t a b ->
  Property
lensSettingProducesValidOnValid :: Lens s t a b -> Property
lensSettingProducesValidOnValid Lens s t a b
l =
  Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
forall s b t a.
(Show s, Show b, Show t, Validity t) =>
Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensSettingProducesValidOnGen Lens s t a b
l Gen b
forall a. GenValid a => Gen a
genValid b -> [b]
forall a. GenValid a => a -> [a]
shrinkValid Gen s
forall a. GenValid a => Gen a
genValid s -> [s]
forall a. GenValid a => a -> [a]
shrinkValid

-- | A property combinator to test whether setting unchecked values via a lens on unchecked values produces valid values.
--
-- Example usage:
--
-- prop> lensSettingProducesValid ((_2) :: Lens (Int, Int) (Int, Int) Int Int)
lensSettingProducesValid ::
  (Show s, GenUnchecked s, Show b, GenUnchecked b, Show t, Validity t) =>
  Lens s t a b ->
  Property
lensSettingProducesValid :: Lens s t a b -> Property
lensSettingProducesValid Lens s t a b
l =
  Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
forall s b t a.
(Show s, Show b, Show t, Validity t) =>
Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensSettingProducesValidOnGen
    Lens s t a b
l
    Gen b
forall a. GenUnchecked a => Gen a
genUnchecked
    b -> [b]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked
    Gen s
forall a. GenUnchecked a => Gen a
genUnchecked
    s -> [s]
forall a. GenUnchecked a => a -> [a]
shrinkUnchecked

-- | A property combinator to test whether setting arbitrary values via a lens on arbitrary values produces valid values.
--
-- Example usage:
--
-- prop> lensSettingProducesValidOnArbitrary ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational)
lensSettingProducesValidOnArbitrary ::
  (Show s, Arbitrary s, Show b, Arbitrary b, Show t, Validity t) =>
  Lens s t a b ->
  Property
lensSettingProducesValidOnArbitrary :: Lens s t a b -> Property
lensSettingProducesValidOnArbitrary Lens s t a b
l =
  Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
forall s b t a.
(Show s, Show b, Show t, Validity t) =>
Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensSettingProducesValidOnGen Lens s t a b
l Gen b
forall a. Arbitrary a => Gen a
arbitrary b -> [b]
forall a. Arbitrary a => a -> [a]
shrink Gen s
forall a. Arbitrary a => Gen a
arbitrary s -> [s]
forall a. Arbitrary a => a -> [a]
shrink

-- | A property combinator to test whether setting values generated by given a generator via a lens on values generated by a given generator produces valid values.
--
-- > isValid (set l b s)
--
-- Example usage:
--
-- prop> lensSettingProducesValidOnGen ((_2) :: Lens (Rational, Rational) (Rational, Rational) Rational Rational) genValid shrinkValid genValid shrinkValid
lensSettingProducesValidOnGen ::
  (Show s, Show b, Show t, Validity t) =>
  Lens s t a b ->
  Gen b ->
  (b -> [b]) ->
  Gen s ->
  (s -> [s]) ->
  Property
lensSettingProducesValidOnGen :: Lens s t a b
-> Gen b -> (b -> [b]) -> Gen s -> (s -> [s]) -> Property
lensSettingProducesValidOnGen Lens s t a b
l Gen b
genB b -> [b]
shrinkB Gen s
genS s -> [s]
shrinkS =
  Gen s -> (s -> [s]) -> (s -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen s
genS s -> [s]
shrinkS ((s -> Property) -> Property) -> (s -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \s
s ->
    Gen b -> (b -> [b]) -> (b -> IO ()) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> [a]) -> (a -> prop) -> Property
forAllShrink Gen b
genB b -> [b]
shrinkB ((b -> IO ()) -> Property) -> (b -> IO ()) -> Property
forall a b. (a -> b) -> a -> b
$ \b
b -> t -> IO ()
forall a. (Show a, Validity a) => a -> IO ()
shouldBeValid (t -> IO ()) -> t -> IO ()
forall a b. (a -> b) -> a -> b
$ ASetter s t a b -> b -> s -> t
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter s t a b
Lens s t a b
l b
b s
s