foldl-exceptions-1.0.0.1: test-suite/test-foldl-exceptions/Main.hs
{-# LANGUAGE TemplateHaskell #-}
module Main (main) where
import Control.Foldl.Exceptions
import Control.Exception
import Control.Monad
import Control.Monad.IO.Class
import Hedgehog
import System.Exit
import System.IO
import qualified Control.Foldl as L
main :: IO ()
main = do
hSetEncoding stdout utf8
hSetEncoding stderr utf8
ok <- checkParallel $$discover
when (not ok) exitFailure
prop_1 :: Property
prop_1 = withTests 1 $ property $ do
let f x = if x < 10 then return x else throw Overflow
let xs = [1, 2, 500, 4] :: [Integer]
-- Since (f 500) produces an exception, the following fold fails:
let fold1 = L.premapM f (L.generalize L.list)
r1 :: Either ArithException [Integer] <- liftIO $ try $ L.foldM fold1 xs
r1 === Left Overflow
-- By applying 'untilFirstException', we can produce a new fold that returns
-- the intermediate result at the point where the exception occurs.
let fold2 = exHalt_ fold1
r2 :: [Integer] <- liftIO $ L.foldM fold2 xs
r2 === [1, 2]
prop_2 :: Property
prop_2 = withTests 1 $ property $ do
let f x = if x < 10 then return x else throw Overflow
let xs = [1, 2, 500, 4] :: [Integer]
let fold1 = L.premapM f (L.generalize L.list)
let fold2 = exHalt @ArithException fold1
r :: (Maybe ArithException, [Integer]) <- liftIO $ L.foldM fold2 xs
r === (Just Overflow, [1, 2])
prop_3 :: Property
prop_3 = withTests 1 $ property $ do
let f x = if x < 10 then return x else throw Overflow
let xs = [1, 2, 500, 4] :: [Integer]
-- Since (f 500) produces an exception, the following fold fails:
let fold1 = L.premapM f (L.generalize L.list)
r1 :: Either ArithException [Integer] <- liftIO $ try $ L.foldM fold1 xs
r1 === Left Overflow
-- By applying 'exSkip_', we can produce a new fold that produces
-- a result from all steps that /don't/ fail:
let fold2 = exSkip_ fold1
r2 :: [Integer] <- liftIO $ L.foldM fold2 xs
r2 === [1, 2, 4]
prop_4 :: Property
prop_4 = withTests 1 $ property $ do
let f x = if x < 10 then return x else throw Overflow
let xs = [1, 2, 500, 4] :: [Integer]
-- Since (f 500) produces an exception, the following fold fails:
let fold1 = L.premapM f (L.generalize L.list)
r1 :: Either ArithException [Integer] <- liftIO $ try $ L.foldM fold1 xs
r1 === Left Overflow
-- By applying 'exSkip', we can produce a new fold that produces
-- a result from all steps that /don't/ fail:
let fold2 = exSkip @ArithException fold1
r2 :: ([ArithException], [Integer]) <- liftIO $ L.foldM fold2 xs
r2 === ([Overflow], [1, 2, 4])