-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Simple, expressive testing library -- -- EasyTest is a simple testing toolkit for unit- and property-testing. -- It's based on the hedgehog property-testing system. Here's an example -- usage: -- --
-- module Main where -- -- import EasyTest -- import qualified Hedgehog.Gen as Gen -- import qualified Hedgehog.Range as Range -- -- suite :: Test -- suite = tests -- [ scope "addition.ex1" $ unitTest $ 1 + 1 === 2 -- , scope "addition.ex2" $ unitTest $ 2 + 3 === 5 -- , scope "list.reversal" $ property $ do -- ns <- forAll $ -- Gen.list (Range.singleton 10) (Gen.int Range.constantBounded) -- reverse (reverse ns) === ns -- -- equivalent to `scope "addition.ex3"` -- , scope "addition" . scope "ex3" $ unitTest $ 3 + 3 === 6 -- , scope "always passes" $ unitTest success -- record a success result -- , scope "failing test" $ crash "oh noes!!" -- ] -- -- -- NB: `run suite` would run all tests, but we only run -- -- tests whose scopes are prefixed by "addition" -- main :: IO Summary -- main = runOnly "addition" suite ---- -- This generates the output: -- --
-- ━━━ runOnly "addition" ━━━ -- ✓ addition.ex1 passed 1 test. -- ✓ addition.ex2 passed 1 test. -- ⚐ list.reversal gave up after 1 discard, passed 0 tests. -- ✓ addition.ex3 passed 1 test. -- ⚐ always passes gave up after 1 discard, passed 0 tests. -- ⚐ failing test gave up after 1 discard, passed 0 tests. -- ⚐ 3 gave up, 3 succeeded. ---- -- We write tests with ordinary Haskell code, with control flow explicit -- and under programmer control. @package easytest @version 0.3 -- | This module defines recheckSeed, which just checks a -- Group using a given seed. module EasyTest.Internal.Hedgehog -- | checkSequential modified to take a seed and exit on failure recheckSeed :: MonadIO m => Seed -> Group -> m Summary -- | This module defines the core internals and interface of easytest. module EasyTest.Internal -- | Run a list of tests tests :: [Test] -> Test -- | Label a test. Can be nested. A "." is placed between nested scopes, so -- scope "foo" . scope "bar" is equivalent to scope -- "foo.bar" scope :: String -> Test -> Test -- | Explicitly skip this set of tests. skip :: Test -> Test -- | Run a unit test (same as unitTest). Example: -- --
-- >>> run $ example $ 1 === 2 -- > ━━━ run ━━━ -- > ✗ (unnamed) failed after 1 test. -- > -- > ┏━━ tests/Suite.hs ━━━ -- > 26 ┃ main :: IO () -- > 27 ┃ main = do -- > 28 ┃ run $ example $ 1 === (2 :: Int) -- > ┃ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- > ┃ │ Failed (- lhs =/= + rhs) -- > ┃ │ - 1 -- > ┃ │ + 2 -- > -- > This failure can be reproduced by running: -- > > recheck (Size 0) (Seed 2914818620245020776 12314041441884757111) (unnamed) -- > -- > ✗ 1 failed. --example :: HasCallStack => PropertyT IO () -> Test -- | Run a unit test (same as example). Example: -- --
-- >>> run $ unitTest $ 1 === 2 -- > ━━━ run ━━━ -- > ✗ (unnamed) failed after 1 test. -- > -- > ┏━━ tests/Suite.hs ━━━ -- > 26 ┃ main :: IO () -- > 27 ┃ main = do -- > 28 ┃ run $ unitTest $ 1 === (2 :: Int) -- > ┃ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- > ┃ │ Failed (- lhs =/= + rhs) -- > ┃ │ - 1 -- > ┃ │ + 2 -- > -- > This failure can be reproduced by running: -- > > recheck (Size 0) (Seed 2914818620245020776 12314041441884757111) (unnamed) -- > -- > ✗ 1 failed. --unitTest :: HasCallStack => PropertyT IO () -> Test -- | Run a property test. Example: -- --
-- >>> run $ scope "list reversal" $ property $ do -- >.. list <- forAll $ Gen.list @_ @Int (Range.linear 0 100) -- >.. (Gen.element [0..100]) -- >.. reverse (reverse list) === list -- > ━━━ run ━━━ -- > ✓ list reversal passed 100 tests. -- > ✓ 1 succeeded. --property :: HasCallStack => PropertyT IO () -> Test -- | Run a property test with a custom configuration. This allows you to -- configure the propertyTestLimit, propertyDiscardLimit, -- propertyShrinkLimit, or propertyShrinkRetries. Example: -- --
-- >>> run $ scope "list reversal" $ propertyWith (defaultConfig { propertyTestLimit = 500 }) $ do
-- >.. list <- forAll $ Gen.list @_ @Int (Range.linear 0 100)
-- >.. (Gen.element [0..100])
-- >.. reverse (reverse list) === list
-- > ━━━ run ━━━
-- > ✓ list reversal passed 500 tests.
-- > ✓ 1 succeeded.
--
propertyWith :: HasCallStack => PropertyConfig -> PropertyT IO () -> Test
-- | Test whether a Prism matches. Example:
--
-- -- >>> main -- > ━━━ run ━━━ -- > ✓ (unnamed) passed 1 test. -- > ✗ (unnamed) failed after 1 test. -- > -- > ┏━━ tests/Suite.hs ━━━ -- > 48 ┃ main :: IO () -- > 49 ┃ main = do -- > 50 ┃ _ <- run $ tests -- > 51 ┃ [ example $ matches _Left (Left 1 :: Either Int ()) -- > 52 ┃ , example $ matches _Left (Right () :: Either Int ()) -- > ┃ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- > 53 ┃ ] -- > 54 ┃ pure () -- > -- > Prism failed to match -- > -- > This failure can be reproduced by running: -- > > recheck (Size 0) (Seed 14003809197113786240 2614482618840800713) (unnamed) -- > -- > ✗ 1 failed, 1 succeeded. ---- -- Use with _Just, _Nothing, _Left, _Right, -- or Control.Lens.Prism matches :: HasCallStack => Prism' s a -> s -> PropertyT IO () -- | Test whether a Prism doesn't match. Compare with -- matches. doesn'tMatch :: HasCallStack => Prism' s a -> s -> PropertyT IO () -- | Mark a test as pending. pending :: String -> PropertyT IO () -- | Record a failure with a given message crash :: HasCallStack => String -> PropertyT IO () -- | Run all tests run :: Test -> IO Summary -- | Run all tests whose scope starts with the given prefix. -- --
-- >>> runOnly "components.a" tests --runOnly :: String -> Test -> IO Summary -- | Rerun all tests with the given seed -- --
-- >>> rerun (Seed 2914818620245020776 12314041441884757111) tests --rerun :: Seed -> Test -> IO Summary -- | Rerun all tests with the given seed and whose scope starts with the -- given prefix -- --
-- >>> rerunOnly "components.a" (Seed 2914818620245020776 12314041441884757111) tests --rerunOnly :: String -> Seed -> Test -> IO Summary -- | Make a test with setup and teardown steps. bracket :: IO a -> (a -> IO ()) -> (a -> PropertyT IO ()) -> PropertyT IO () -- | A variant of bracket where the return value from the setup step -- is not required. bracket_ :: IO a -> IO b -> PropertyT IO () -> PropertyT IO () -- | A specialised variant of bracket with just a teardown step. finally :: PropertyT IO () -> IO a -> PropertyT IO () -- | Make this a cabal test suite for use with exitcode-stdio-1.0 -- test-suites. -- -- This simply checks to see if any tests failed and if so exits with -- exitFailure. cabalTestSuite :: IO Summary -> IO () -- | A prism embodies one constructor of a sum type (as a lens embodies one -- part of a product type). See _Just, _Nothing, -- _Left, and _Right for examples. See -- Control.Lens.Prism for more explanation. type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t) -- | A type-restricted prism. See Control.Lens.Prism for more -- explanation. type Prism' s a = Prism s s a a -- | Unit- or property- test. data TestType Unit :: TestType Prop :: PropertyConfig -> TestType -- | A set of unit- and property-tests data Test -- | A set of named (scoped) tests NamedTests :: ![(String, Test)] -> Test -- | A sequence of tests Sequence :: ![Test] -> Test -- | An atomic unit- or property-test Leaf :: !TestType -> !PropertyT IO () -> Test -- | A set of tests marked to skip Skipped :: !Test -> Test -- | A property test, along with some configurable limits like how many -- times to run the test. data Property -- | The property monad transformer allows both the generation of test -- inputs and the assertion of expectations. data PropertyT (m :: Type -> Type) a class Monad m => MonadTest (m :: Type -> Type) -- | Fails the test if the two arguments provided are not equal. (===) :: (MonadTest m, Eq a, Show a, HasCallStack) => a -> a -> m () infix 4 === -- | Fails the test if the two arguments provided are equal. (/==) :: (MonadTest m, Eq a, Show a, HasCallStack) => a -> a -> m () infix 4 /== -- | A splittable random number generator. data Seed -- | A summary of all the properties executed. data Summary Summary :: !PropertyCount -> !PropertyCount -> !PropertyCount -> !PropertyCount -> !PropertyCount -> Summary [summaryWaiting] :: Summary -> !PropertyCount [summaryRunning] :: Summary -> !PropertyCount [summaryFailed] :: Summary -> !PropertyCount [summaryGaveUp] :: Summary -> !PropertyCount [summaryOK] :: Summary -> !PropertyCount -- | Configuration for a property test. data PropertyConfig PropertyConfig :: !TestLimit -> !DiscardLimit -> !ShrinkLimit -> !ShrinkRetries -> PropertyConfig [propertyTestLimit] :: PropertyConfig -> !TestLimit [propertyDiscardLimit] :: PropertyConfig -> !DiscardLimit [propertyShrinkLimit] :: PropertyConfig -> !ShrinkLimit [propertyShrinkRetries] :: PropertyConfig -> !ShrinkRetries -- | The default configuration for a property test. defaultConfig :: PropertyConfig -- | EasyTest is a simple testing toolkit for unit- and property-testing. -- It's based on the hedgehog property-testing system. Here's an -- example usage: -- --
-- module Main where -- -- import EasyTest -- import qualified Hedgehog.Gen as Gen -- import qualified Hedgehog.Range as Range -- -- suite :: Test -- suite = tests -- [ scope "addition.ex" $ unitTest $ 1 + 1 === 2 -- , scope "list.reversal" $ property $ do -- ns <- forAll $ -- Gen.list (Range.singleton 10) (Gen.int Range.constantBounded) -- reverse (reverse ns) === ns -- -- equivalent to `scope "addition.ex3"` -- , scope "addition" . scope "ex3" $ unitTest $ 3 + 3 === 6 -- , scope "always passes" $ unitTest success -- record a success result -- , scope "failing test" $ unitTest $ crash "oh noes!!" -- ] -- -- -- NB: `run suite` would run all tests, but we only run -- -- tests whose scopes are prefixed by "addition" -- main :: IO Summary -- main = runOnly "addition" suite ---- -- This generates the output: -- --
-- ━━━ runOnly "addition" ━━━ -- ✓ addition.ex1 passed 1 test. -- ✓ addition.ex2 passed 1 test. -- ⚐ list.reversal gave up after 1 discard, passed 0 tests. -- ✓ addition.ex3 passed 1 test. -- ⚐ always passes gave up after 1 discard, passed 0 tests. -- ⚐ failing test gave up after 1 discard, passed 0 tests. -- ⚐ 3 gave up, 3 succeeded. ---- -- We write tests with ordinary Haskell code, with control flow explicit -- and under programmer control. -- --
-- -- | Label a test. Can be nested. A `'.'` is placed between nested -- -- scopes, so `scope "foo" . scope "bar"` is equivalent to `scope "foo.bar"` -- scope :: String -> Test -> Test ---- -- Here's an example usage: -- --
-- module Main where -- -- import EasyTest -- (Test, scope, crash, run, tests, example, success, (===), Summary) -- -- suite :: Test -- suite = tests -- [ example success -- , scope "test-crash" $ example $ crash "oh noes!" -- , example $ 1 + 1 === 2 -- ] -- -- main :: IO Summary -- main = run suite ---- -- This example runs the three examples in order so that they're all -- tested. The output is: -- --
-- ━━━ run ━━━ -- ✓ (unnamed) passed 1 test. -- ✗ test-crash failed after 1 test. -- -- ┏━━ tests/Suite.hs ━━━ -- 6 ┃ suite :: Test -- 7 ┃ suite = tests -- 8 ┃ [ example success -- 9 ┃ , scope "test-crash" $ example $ crash "oh noes!" -- ┃ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- 10 ┃ , example $ 1 + 1 === 2 -- 11 ┃ ] -- -- oh noes! -- -- This failure can be reproduced by running: -- > recheck (Size 0) (Seed 12444749623322829837 10053881125821732685) test-crash -- -- ✓ (unnamed) passed 1 test. -- ✗ 1 failed, 2 succeeded. ---- -- In the output, we get a stack trace pointing to the line where crash -- was called (..tests/Suite.hs:9), information about failing -- tests, and instructions for rerunning the tests with an identical -- random seed (in this case, there's no randomness, so rerun -- would work fine, but if our test generated random data, we might want -- to rerun with the exact same random numbers). Note that, somewhat -- embarrassingly, the error message currently gives bad instructions and -- the correct way to rerun the tests is with rerun (Seed -- 12444749623322829837 10053881125821732685) suite. -- -- The various run functions (run, runOnly, rerun, -- and rerunOnly) all return a hedgehog Summary. Use -- cabalTestSuite to exit the process with a nonzero status in the -- event of a failure, for use with exitcode-stdio-1.0 cabal -- test-suites. Here's an example cabal file: -- --
-- test-suite tests -- type: exitcode-stdio-1.0 -- main-is: NameOfYourTestSuite.hs -- hs-source-dirs: tests -- other-modules: -- build-depends: -- base, -- easytest ---- -- For tests that are logically separate, we usually combine them into a -- suite using tests, as in: -- --
-- suite = tests -- [ scope "ex1" $ example $ 1 + 1 === 2 -- , scope "ex2" $ example $ 2 + 2 === 4 -- ] ---- --
-- reverseTest :: Test () -- reverseTest = scope "list reversal" $ property $ do -- nums <- forAll $ Gen.list (Range.linear 0 100) (Gen.int (Range.linear 0 99)) -- reverse (reverse nums) === nums ---- -- The above code generates lists of sizes between 0 and 100, consisting -- of Int values in the range 0 through 99. -- -- If our list reversal test failed, we might use runOnly -- "list reversal" or rerunOnly "list reversal" -- <randomseed> to rerun just that subtree of the test suite, -- and we might add some additional diagnostics to see what was going on: -- --
-- import EasyTest -- import qualified Hedgehog.Gen as Gen -- import qualified Hedgehog.Range as Range -- -- reverseTest :: Test () -- reverseTest = property $ do -- nums <- forAll $ -- Gen.list (Range.linear 0 100) (Gen.int (Range.linear 0 99)) -- footnote $ "nums: " ++ show nums -- let r = reverse (reverse nums) -- footnote $ "reverse (reverse nums): " ++ show r -- r === nums ---- -- See the hedgehog docs for more on writing good property tests. -- --
-- scope "bracket-example" $ example $ bracket -- (mkstemp "temp") -- ((filepath, handle) -> hClose handle >> removeFile filepath) -- ((_filepath, handle) -> do -- liftIO $ hPutStrLn handle "this temporary file will be cleaned up" -- success) ---- -- bracket ensures that the resource is cleaned up, even if the -- test throws an exception. You can write either property- or unit- -- tests in this style. module EasyTest -- | A set of unit- and property-tests data Test -- | Run a list of tests tests :: [Test] -> Test -- | Label a test. Can be nested. A "." is placed between nested scopes, so -- scope "foo" . scope "bar" is equivalent to scope -- "foo.bar" scope :: String -> Test -> Test -- | Run a unit test (same as unitTest). Example: -- --
-- >>> run $ example $ 1 === 2 -- > ━━━ run ━━━ -- > ✗ (unnamed) failed after 1 test. -- > -- > ┏━━ tests/Suite.hs ━━━ -- > 26 ┃ main :: IO () -- > 27 ┃ main = do -- > 28 ┃ run $ example $ 1 === (2 :: Int) -- > ┃ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- > ┃ │ Failed (- lhs =/= + rhs) -- > ┃ │ - 1 -- > ┃ │ + 2 -- > -- > This failure can be reproduced by running: -- > > recheck (Size 0) (Seed 2914818620245020776 12314041441884757111) (unnamed) -- > -- > ✗ 1 failed. --example :: HasCallStack => PropertyT IO () -> Test -- | Run a unit test (same as example). Example: -- --
-- >>> run $ unitTest $ 1 === 2 -- > ━━━ run ━━━ -- > ✗ (unnamed) failed after 1 test. -- > -- > ┏━━ tests/Suite.hs ━━━ -- > 26 ┃ main :: IO () -- > 27 ┃ main = do -- > 28 ┃ run $ unitTest $ 1 === (2 :: Int) -- > ┃ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- > ┃ │ Failed (- lhs =/= + rhs) -- > ┃ │ - 1 -- > ┃ │ + 2 -- > -- > This failure can be reproduced by running: -- > > recheck (Size 0) (Seed 2914818620245020776 12314041441884757111) (unnamed) -- > -- > ✗ 1 failed. --unitTest :: HasCallStack => PropertyT IO () -> Test -- | Run a property test. Example: -- --
-- >>> run $ scope "list reversal" $ property $ do -- >.. list <- forAll $ Gen.list @_ @Int (Range.linear 0 100) -- >.. (Gen.element [0..100]) -- >.. reverse (reverse list) === list -- > ━━━ run ━━━ -- > ✓ list reversal passed 100 tests. -- > ✓ 1 succeeded. --property :: HasCallStack => PropertyT IO () -> Test -- | Run a property test with a custom configuration. This allows you to -- configure the propertyTestLimit, propertyDiscardLimit, -- propertyShrinkLimit, or propertyShrinkRetries. Example: -- --
-- >>> run $ scope "list reversal" $ propertyWith (defaultConfig { propertyTestLimit = 500 }) $ do
-- >.. list <- forAll $ Gen.list @_ @Int (Range.linear 0 100)
-- >.. (Gen.element [0..100])
-- >.. reverse (reverse list) === list
-- > ━━━ run ━━━
-- > ✓ list reversal passed 500 tests.
-- > ✓ 1 succeeded.
--
propertyWith :: HasCallStack => PropertyConfig -> PropertyT IO () -> Test
-- | Test whether a Prism matches. Example:
--
-- -- >>> main -- > ━━━ run ━━━ -- > ✓ (unnamed) passed 1 test. -- > ✗ (unnamed) failed after 1 test. -- > -- > ┏━━ tests/Suite.hs ━━━ -- > 48 ┃ main :: IO () -- > 49 ┃ main = do -- > 50 ┃ _ <- run $ tests -- > 51 ┃ [ example $ matches _Left (Left 1 :: Either Int ()) -- > 52 ┃ , example $ matches _Left (Right () :: Either Int ()) -- > ┃ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- > 53 ┃ ] -- > 54 ┃ pure () -- > -- > Prism failed to match -- > -- > This failure can be reproduced by running: -- > > recheck (Size 0) (Seed 14003809197113786240 2614482618840800713) (unnamed) -- > -- > ✗ 1 failed, 1 succeeded. ---- -- Use with _Just, _Nothing, _Left, _Right, -- or Control.Lens.Prism matches :: HasCallStack => Prism' s a -> s -> PropertyT IO () -- | Test whether a Prism doesn't match. Compare with -- matches. doesn'tMatch :: HasCallStack => Prism' s a -> s -> PropertyT IO () -- | Explicitly skip this set of tests. skip :: Test -> Test -- | Mark a test as pending. pending :: String -> PropertyT IO () -- | Record a failure with a given message crash :: HasCallStack => String -> PropertyT IO () -- | Run all tests run :: Test -> IO Summary -- | Run all tests whose scope starts with the given prefix. -- --
-- >>> runOnly "components.a" tests --runOnly :: String -> Test -> IO Summary -- | Rerun all tests with the given seed -- --
-- >>> rerun (Seed 2914818620245020776 12314041441884757111) tests --rerun :: Seed -> Test -> IO Summary -- | Rerun all tests with the given seed and whose scope starts with the -- given prefix -- --
-- >>> rerunOnly "components.a" (Seed 2914818620245020776 12314041441884757111) tests --rerunOnly :: String -> Seed -> Test -> IO Summary -- | Make a test with setup and teardown steps. bracket :: IO a -> (a -> IO ()) -> (a -> PropertyT IO ()) -> PropertyT IO () -- | A variant of bracket where the return value from the setup step -- is not required. bracket_ :: IO a -> IO b -> PropertyT IO () -> PropertyT IO () -- | A specialised variant of bracket with just a teardown step. finally :: PropertyT IO () -> IO a -> PropertyT IO () -- | Make this a cabal test suite for use with exitcode-stdio-1.0 -- test-suites. -- -- This simply checks to see if any tests failed and if so exits with -- exitFailure. cabalTestSuite :: IO Summary -> IO () -- | Another name for pure (). success :: MonadTest m => m () -- | Causes a test to fail. failure :: (MonadTest m, HasCallStack) => m a -- | Fails the test if the condition provided is False. assert :: (MonadTest m, HasCallStack) => Bool -> m () -- | Fails the test if the two arguments provided are not equal. (===) :: (MonadTest m, Eq a, Show a, HasCallStack) => a -> a -> m () infix 4 === -- | Fails the test if the two arguments provided are equal. (/==) :: (MonadTest m, Eq a, Show a, HasCallStack) => a -> a -> m () infix 4 /== -- | A splittable random number generator. data Seed Seed :: !Word64 -> !Word64 -> Seed [seedValue] :: Seed -> !Word64 -- | must be an odd number [seedGamma] :: Seed -> !Word64 -- | A summary of all the properties executed. data Summary -- | Logs a message to be displayed as additional information in the footer -- of the failure report. footnote :: MonadTest m => String -> m () -- | Annotates the source code with a message that might be useful for -- debugging a test failure. annotate :: (MonadTest m, HasCallStack) => String -> m () -- | Generates a random input for the test by running the provided -- generator. forAll :: (Monad m, Show a, HasCallStack) => Gen a -> PropertyT m a -- | The property monad transformer allows both the generation of test -- inputs and the assertion of expectations. data PropertyT (m :: Type -> Type) a -- | Configuration for a property test. data PropertyConfig PropertyConfig :: !TestLimit -> !DiscardLimit -> !ShrinkLimit -> !ShrinkRetries -> PropertyConfig [propertyTestLimit] :: PropertyConfig -> !TestLimit [propertyDiscardLimit] :: PropertyConfig -> !DiscardLimit [propertyShrinkLimit] :: PropertyConfig -> !ShrinkLimit [propertyShrinkRetries] :: PropertyConfig -> !ShrinkRetries -- | The default configuration for a property test. defaultConfig :: PropertyConfig -- | This module defines lens-style prisms for use with matches / -- doesn'tMatch. These are equivalent and compatible with the -- definitions in Control.Lens.Prism. module EasyTest.Prism -- | Prism to the Left half of an Either _Left :: Prism (Either a c) (Either b c) a b -- | Prism to the Right half of an Either _Right :: Prism (Either c a) (Either c b) a b -- | Prism to the Just in a Maybe _Just :: Prism (Maybe a) (Maybe b) a b -- | Prism to the Nothing in a Maybe _Nothing :: Prism' (Maybe a) () -- | This Prism compares for exact equality with a given value. -- --
-- >>> only 4 # () -- 4 ---- --
-- >>> 5 ^? only 4 -- Nothing --only :: Eq a => a -> Prism' a () -- | This Prism compares for approximate equality with a given value -- and a predicate for testing, an example where the value is the empty -- list and the predicate checks that a list is empty (same as -- _Empty with the AsEmpty list instance): -- --
-- >>> nearly [] null # () -- [] -- -- >>> [1,2,3,4] ^? nearly [] null -- Nothing ---- --
-- nearly [] null :: Prism' [a] () ---- -- To comply with the Prism laws the arguments you supply to -- nearly a p are somewhat constrained. -- -- We assume p x holds iff x ≡ a. Under that assumption -- then this is a valid Prism. -- -- This is useful when working with a type where you can test equality -- for only a subset of its values, and the prism selects such a value. nearly :: a -> (a -> Bool) -> Prism' a () -- | A prism embodies one constructor of a sum type (as a lens embodies one -- part of a product type). See _Just, _Nothing, -- _Left, and _Right for examples. See -- Control.Lens.Prism for more explanation. type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t) -- | A type-restricted prism. See Control.Lens.Prism for more -- explanation. type Prism' s a = Prism s s a a