module Test.Check.Function.CoListable
where
import Test.Check.Core
import Test.Check.Utils
import Data.Maybe (fromMaybe)
(\+:/) :: [[a]] -> [[a]] -> [[a]]
xss \+:/ yss = xss \/ ([]:yss)
infixr 9 \+:/
class CoListable a where
coListing :: [[b]] -> [[a -> b]]
instance CoListable () where
coListing rs = mapT (\r () -> r) rs
instance CoListable Bool where
coListing rs = productWith (\r1 r2 b -> if b then r1 else r2) rs rs
instance CoListable a => CoListable (Maybe a) where
coListing rs = productWith (\z f m -> case m of Nothing -> z
Just x -> f x) rs (coListing rs)
instance (CoListable a, CoListable b) => CoListable (Either a b) where
coListing rs = productWith (\f g e -> case e of Left x -> f x
Right x -> g x) (coListing rs) (coListing rs)
instance (CoListable a) => CoListable [a] where
coListing rss = mapT const rss
\+:/ productWith (\y f xs -> case xs of [] -> y
(x:xs') -> f x xs') rss (coListing (coListing rss))
instance CoListable Int where
coListing rss = mapT const rss
\+:/ product3With (\f g z i -> if i > 0 then f (i1)
else if i < 0 then g (i+1)
else z) (coListing rss) (coListing rss) rss
alts0 :: [[a]] -> [[a]]
alts0 = id
alts1 :: CoListable a => [[b]] -> [[a->b]]
alts1 bs = coListing bs
alts2 :: (CoListable a, CoListable b) => [[c]] -> [[a->b->c]]
alts2 cs = coListing (coListing cs)
alts3 :: (CoListable a, CoListable b, CoListable c) => [[d]] -> [[a->b->c->d]]
alts3 ds = coListing (coListing (coListing ds))
fListing :: (CoListable a, Listable b) => [[a->b]]
fListing = coListing tiers