{-# LANGUAGE DerivingVia       #-}
{-# LANGUAGE DeriveTraversable #-}
module Data.Profunctor.Counting(
  Counting(..)
) where

import Data.Functor.Classes
import Control.Applicative
import Data.Functor.Contravariant
import Data.Functor.Contravariant.Divisible
import Data.Bifunctor

import Data.Profunctor
import Data.Profunctor.Cartesian

import Data.Coerce

newtype Counting a b = Counting { forall a b. Counting a b -> Int
getCounting :: Int }
  deriving stock (Int -> Counting a b -> ShowS
[Counting a b] -> ShowS
Counting a b -> String
(Int -> Counting a b -> ShowS)
-> (Counting a b -> String)
-> ([Counting a b] -> ShowS)
-> Show (Counting a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b. Int -> Counting a b -> ShowS
forall a b. [Counting a b] -> ShowS
forall a b. Counting a b -> String
$cshowsPrec :: forall a b. Int -> Counting a b -> ShowS
showsPrec :: Int -> Counting a b -> ShowS
$cshow :: forall a b. Counting a b -> String
show :: Counting a b -> String
$cshowList :: forall a b. [Counting a b] -> ShowS
showList :: [Counting a b] -> ShowS
Show, ReadPrec [Counting a b]
ReadPrec (Counting a b)
Int -> ReadS (Counting a b)
ReadS [Counting a b]
(Int -> ReadS (Counting a b))
-> ReadS [Counting a b]
-> ReadPrec (Counting a b)
-> ReadPrec [Counting a b]
-> Read (Counting a b)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall a b. ReadPrec [Counting a b]
forall a b. ReadPrec (Counting a b)
forall a b. Int -> ReadS (Counting a b)
forall a b. ReadS [Counting a b]
$creadsPrec :: forall a b. Int -> ReadS (Counting a b)
readsPrec :: Int -> ReadS (Counting a b)
$creadList :: forall a b. ReadS [Counting a b]
readList :: ReadS [Counting a b]
$creadPrec :: forall a b. ReadPrec (Counting a b)
readPrec :: ReadPrec (Counting a b)
$creadListPrec :: forall a b. ReadPrec [Counting a b]
readListPrec :: ReadPrec [Counting a b]
Read, Counting a b -> Counting a b -> Bool
(Counting a b -> Counting a b -> Bool)
-> (Counting a b -> Counting a b -> Bool) -> Eq (Counting a b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b. Counting a b -> Counting a b -> Bool
$c== :: forall a b. Counting a b -> Counting a b -> Bool
== :: Counting a b -> Counting a b -> Bool
$c/= :: forall a b. Counting a b -> Counting a b -> Bool
/= :: Counting a b -> Counting a b -> Bool
Eq, Eq (Counting a b)
Eq (Counting a b) =>
(Counting a b -> Counting a b -> Ordering)
-> (Counting a b -> Counting a b -> Bool)
-> (Counting a b -> Counting a b -> Bool)
-> (Counting a b -> Counting a b -> Bool)
-> (Counting a b -> Counting a b -> Bool)
-> (Counting a b -> Counting a b -> Counting a b)
-> (Counting a b -> Counting a b -> Counting a b)
-> Ord (Counting a b)
Counting a b -> Counting a b -> Bool
Counting a b -> Counting a b -> Ordering
Counting a b -> Counting a b -> Counting a b
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a b. Eq (Counting a b)
forall a b. Counting a b -> Counting a b -> Bool
forall a b. Counting a b -> Counting a b -> Ordering
forall a b. Counting a b -> Counting a b -> Counting a b
$ccompare :: forall a b. Counting a b -> Counting a b -> Ordering
compare :: Counting a b -> Counting a b -> Ordering
$c< :: forall a b. Counting a b -> Counting a b -> Bool
< :: Counting a b -> Counting a b -> Bool
$c<= :: forall a b. Counting a b -> Counting a b -> Bool
<= :: Counting a b -> Counting a b -> Bool
$c> :: forall a b. Counting a b -> Counting a b -> Bool
> :: Counting a b -> Counting a b -> Bool
$c>= :: forall a b. Counting a b -> Counting a b -> Bool
>= :: Counting a b -> Counting a b -> Bool
$cmax :: forall a b. Counting a b -> Counting a b -> Counting a b
max :: Counting a b -> Counting a b -> Counting a b
$cmin :: forall a b. Counting a b -> Counting a b -> Counting a b
min :: Counting a b -> Counting a b -> Counting a b
Ord, (forall a b. (a -> b) -> Counting a a -> Counting a b)
-> (forall a b. a -> Counting a b -> Counting a a)
-> Functor (Counting a)
forall a b. a -> Counting a b -> Counting a a
forall a b. (a -> b) -> Counting a a -> Counting a b
forall a a b. a -> Counting a b -> Counting a a
forall a a b. (a -> b) -> Counting a a -> Counting a b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a a b. (a -> b) -> Counting a a -> Counting a b
fmap :: forall a b. (a -> b) -> Counting a a -> Counting a b
$c<$ :: forall a a b. a -> Counting a b -> Counting a a
<$ :: forall a b. a -> Counting a b -> Counting a a
Functor, (forall m. Monoid m => Counting a m -> m)
-> (forall m a. Monoid m => (a -> m) -> Counting a a -> m)
-> (forall m a. Monoid m => (a -> m) -> Counting a a -> m)
-> (forall a b. (a -> b -> b) -> b -> Counting a a -> b)
-> (forall a b. (a -> b -> b) -> b -> Counting a a -> b)
-> (forall b a. (b -> a -> b) -> b -> Counting a a -> b)
-> (forall b a. (b -> a -> b) -> b -> Counting a a -> b)
-> (forall a. (a -> a -> a) -> Counting a a -> a)
-> (forall a. (a -> a -> a) -> Counting a a -> a)
-> (forall a. Counting a a -> [a])
-> (forall a. Counting a a -> Bool)
-> (forall a. Counting a a -> Int)
-> (forall a. Eq a => a -> Counting a a -> Bool)
-> (forall a. Ord a => Counting a a -> a)
-> (forall a. Ord a => Counting a a -> a)
-> (forall a. Num a => Counting a a -> a)
-> (forall a. Num a => Counting a a -> a)
-> Foldable (Counting a)
forall a. Eq a => a -> Counting a a -> Bool
forall a. Num a => Counting a a -> a
forall a. Ord a => Counting a a -> a
forall m. Monoid m => Counting a m -> m
forall a. Counting a a -> Bool
forall a. Counting a a -> Int
forall a. Counting a a -> [a]
forall a. (a -> a -> a) -> Counting a a -> a
forall a a. Eq a => a -> Counting a a -> Bool
forall a a. Num a => Counting a a -> a
forall a a. Ord a => Counting a a -> a
forall a m. Monoid m => Counting a m -> m
forall m a. Monoid m => (a -> m) -> Counting a a -> m
forall a a. Counting a a -> Bool
forall a b. Counting a b -> Int
forall a a. Counting a a -> [a]
forall b a. (b -> a -> b) -> b -> Counting a a -> b
forall a b. (a -> b -> b) -> b -> Counting a a -> b
forall a a. (a -> a -> a) -> Counting a a -> a
forall a m a. Monoid m => (a -> m) -> Counting a a -> m
forall a b a. (b -> a -> b) -> b -> Counting a a -> b
forall a a b. (a -> b -> b) -> b -> Counting a a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall a m. Monoid m => Counting a m -> m
fold :: forall m. Monoid m => Counting a m -> m
$cfoldMap :: forall a m a. Monoid m => (a -> m) -> Counting a a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Counting a a -> m
$cfoldMap' :: forall a m a. Monoid m => (a -> m) -> Counting a a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Counting a a -> m
$cfoldr :: forall a a b. (a -> b -> b) -> b -> Counting a a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Counting a a -> b
$cfoldr' :: forall a a b. (a -> b -> b) -> b -> Counting a a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Counting a a -> b
$cfoldl :: forall a b a. (b -> a -> b) -> b -> Counting a a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Counting a a -> b
$cfoldl' :: forall a b a. (b -> a -> b) -> b -> Counting a a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Counting a a -> b
$cfoldr1 :: forall a a. (a -> a -> a) -> Counting a a -> a
foldr1 :: forall a. (a -> a -> a) -> Counting a a -> a
$cfoldl1 :: forall a a. (a -> a -> a) -> Counting a a -> a
foldl1 :: forall a. (a -> a -> a) -> Counting a a -> a
$ctoList :: forall a a. Counting a a -> [a]
toList :: forall a. Counting a a -> [a]
$cnull :: forall a a. Counting a a -> Bool
null :: forall a. Counting a a -> Bool
$clength :: forall a b. Counting a b -> Int
length :: forall a. Counting a a -> Int
$celem :: forall a a. Eq a => a -> Counting a a -> Bool
elem :: forall a. Eq a => a -> Counting a a -> Bool
$cmaximum :: forall a a. Ord a => Counting a a -> a
maximum :: forall a. Ord a => Counting a a -> a
$cminimum :: forall a a. Ord a => Counting a a -> a
minimum :: forall a. Ord a => Counting a a -> a
$csum :: forall a a. Num a => Counting a a -> a
sum :: forall a. Num a => Counting a a -> a
$cproduct :: forall a a. Num a => Counting a a -> a
product :: forall a. Num a => Counting a a -> a
Foldable, Functor (Counting a)
Foldable (Counting a)
(Functor (Counting a), Foldable (Counting a)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Counting a a -> f (Counting a b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Counting a (f a) -> f (Counting a a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Counting a a -> m (Counting a b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Counting a (m a) -> m (Counting a a))
-> Traversable (Counting a)
forall a. Functor (Counting a)
forall a. Foldable (Counting a)
forall a (m :: * -> *) a.
Monad m =>
Counting a (m a) -> m (Counting a a)
forall a (f :: * -> *) a.
Applicative f =>
Counting a (f a) -> f (Counting a a)
forall a (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Counting a a -> m (Counting a b)
forall a (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Counting a a -> f (Counting a b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
Counting a (m a) -> m (Counting a a)
forall (f :: * -> *) a.
Applicative f =>
Counting a (f a) -> f (Counting a a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Counting a a -> m (Counting a b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Counting a a -> f (Counting a b)
$ctraverse :: forall a (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Counting a a -> f (Counting a b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Counting a a -> f (Counting a b)
$csequenceA :: forall a (f :: * -> *) a.
Applicative f =>
Counting a (f a) -> f (Counting a a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Counting a (f a) -> f (Counting a a)
$cmapM :: forall a (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Counting a a -> m (Counting a b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Counting a a -> m (Counting a b)
$csequence :: forall a (m :: * -> *) a.
Monad m =>
Counting a (m a) -> m (Counting a a)
sequence :: forall (m :: * -> *) a.
Monad m =>
Counting a (m a) -> m (Counting a a)
Traversable)
  deriving ((forall a. Eq a => Eq (Counting a a)) =>
(forall a b.
 (a -> b -> Bool) -> Counting a a -> Counting a b -> Bool)
-> Eq1 (Counting a)
forall a. Eq a => Eq (Counting a a)
forall a a. Eq a => Eq (Counting a a)
forall a b.
(a -> b -> Bool) -> Counting a a -> Counting a b -> Bool
forall a a b.
(a -> b -> Bool) -> Counting a a -> Counting a b -> Bool
forall (f :: * -> *).
(forall a. Eq a => Eq (f a)) =>
(forall a b. (a -> b -> Bool) -> f a -> f b -> Bool) -> Eq1 f
$cliftEq :: forall a a b.
(a -> b -> Bool) -> Counting a a -> Counting a b -> Bool
liftEq :: forall a b.
(a -> b -> Bool) -> Counting a a -> Counting a b -> Bool
Eq1, Eq1 (Counting a)
(Eq1 (Counting a), forall a. Ord a => Ord (Counting a a)) =>
(forall a b.
 (a -> b -> Ordering) -> Counting a a -> Counting a b -> Ordering)
-> Ord1 (Counting a)
forall a. Eq1 (Counting a)
forall a. Ord a => Ord (Counting a a)
forall a a. Ord a => Ord (Counting a a)
forall a b.
(a -> b -> Ordering) -> Counting a a -> Counting a b -> Ordering
forall a a b.
(a -> b -> Ordering) -> Counting a a -> Counting a b -> Ordering
forall (f :: * -> *).
(Eq1 f, forall a. Ord a => Ord (f a)) =>
(forall a b. (a -> b -> Ordering) -> f a -> f b -> Ordering)
-> Ord1 f
$cliftCompare :: forall a a b.
(a -> b -> Ordering) -> Counting a a -> Counting a b -> Ordering
liftCompare :: forall a b.
(a -> b -> Ordering) -> Counting a a -> Counting a b -> Ordering
Ord1, (forall a' a. (a' -> a) -> Counting a a -> Counting a a')
-> (forall b a. b -> Counting a b -> Counting a a)
-> Contravariant (Counting a)
forall b a. b -> Counting a b -> Counting a a
forall a' a. (a' -> a) -> Counting a a -> Counting a a'
forall a b a. b -> Counting a b -> Counting a a
forall a a' a. (a' -> a) -> Counting a a -> Counting a a'
forall (f :: * -> *).
(forall a' a. (a' -> a) -> f a -> f a')
-> (forall b a. b -> f b -> f a) -> Contravariant f
$ccontramap :: forall a a' a. (a' -> a) -> Counting a a -> Counting a a'
contramap :: forall a' a. (a' -> a) -> Counting a a -> Counting a a'
$c>$ :: forall a b a. b -> Counting a b -> Counting a a
>$ :: forall b a. b -> Counting a b -> Counting a a
Contravariant)
           via (Const Int)

instance Eq2 Counting where
  liftEq2 :: forall a b c d.
(a -> b -> Bool)
-> (c -> d -> Bool) -> Counting a c -> Counting b d -> Bool
liftEq2 a -> b -> Bool
_ c -> d -> Bool
_ = (Int -> Int -> Bool) -> Counting a c -> Counting b d -> Bool
forall a b. Coercible a b => a -> b
coerce (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==) :: Int -> Int -> Bool)

instance Ord2 Counting where
  liftCompare2 :: forall a b c d.
(a -> b -> Ordering)
-> (c -> d -> Ordering) -> Counting a c -> Counting b d -> Ordering
liftCompare2 a -> b -> Ordering
_ c -> d -> Ordering
_ = (Int -> Int -> Ordering)
-> Counting a c -> Counting b d -> Ordering
forall a b. Coercible a b => a -> b
coerce (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare :: Int -> Int -> Ordering)

instance Profunctor Counting where
  dimap :: forall a b c d.
(a -> b) -> (c -> d) -> Counting b c -> Counting a d
dimap a -> b
_ c -> d
_ = Counting b c -> Counting a d
forall a b. Coercible a b => a -> b
coerce
  lmap :: forall a b c. (a -> b) -> Counting b c -> Counting a c
lmap a -> b
_ = Counting b c -> Counting a c
forall a b. Coercible a b => a -> b
coerce
  rmap :: forall b c a. (b -> c) -> Counting a b -> Counting a c
rmap b -> c
_ = Counting a b -> Counting a c
forall a b. Coercible a b => a -> b
coerce

instance Bifunctor Counting where
  bimap :: forall a b c d.
(a -> b) -> (c -> d) -> Counting a c -> Counting b d
bimap a -> b
_ c -> d
_ = Counting a c -> Counting b d
forall a b. Coercible a b => a -> b
coerce
  first :: forall a b c. (a -> b) -> Counting a c -> Counting b c
first a -> b
_ = Counting a c -> Counting b c
forall a b. Coercible a b => a -> b
coerce
  second :: forall b c a. (b -> c) -> Counting a b -> Counting a c
second b -> c
_ = Counting a b -> Counting a c
forall a b. Coercible a b => a -> b
coerce

instance Cartesian Counting where
  proUnit :: forall a. Counting a ()
proUnit = Int -> Counting a ()
forall a b. Int -> Counting a b
Counting Int
1
  Counting Int
a *** :: forall a b a' b'.
Counting a b -> Counting a' b' -> Counting (a, a') (b, b')
*** Counting Int
b = Int -> Counting (a, a') (b, b')
forall a b. Int -> Counting a b
Counting (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
b)

instance Cocartesian Counting where
  proEmpty :: forall b. Counting Void b
proEmpty = Int -> Counting Void b
forall a b. Int -> Counting a b
Counting Int
0
  Counting Int
a +++ :: forall a b a' b'.
Counting a b
-> Counting a' b' -> Counting (Either a a') (Either b b')
+++ Counting Int
b = Int -> Counting (Either a a') (Either b b')
forall a b. Int -> Counting a b
Counting (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
b)

instance Applicative (Counting x) where
  pure :: forall a. a -> Counting x a
pure a
_ = Int -> Counting x a
forall a b. Int -> Counting a b
Counting Int
1
  Counting Int
a <*> :: forall a b. Counting x (a -> b) -> Counting x a -> Counting x b
<*> Counting Int
b = Int -> Counting x b
forall a b. Int -> Counting a b
Counting (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
b)

instance Alternative (Counting x) where
  empty :: forall a. Counting x a
empty = Int -> Counting x a
forall a b. Int -> Counting a b
Counting Int
0
  Counting Int
a <|> :: forall a. Counting x a -> Counting x a -> Counting x a
<|> Counting Int
b = Int -> Counting x a
forall a b. Int -> Counting a b
Counting (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
b)

instance Divisible (Counting x) where
  conquer :: forall a. Counting x a
conquer = Int -> Counting x a
forall a b. Int -> Counting a b
Counting Int
1
  divide :: forall a b c.
(a -> (b, c)) -> Counting x b -> Counting x c -> Counting x a
divide a -> (b, c)
_ (Counting Int
a) (Counting Int
b) = Int -> Counting x a
forall a b. Int -> Counting a b
Counting (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
b)

instance Decidable (Counting x) where
  lose :: forall a. (a -> Void) -> Counting x a
lose a -> Void
_ = Int -> Counting x a
forall a b. Int -> Counting a b
Counting Int
0
  choose :: forall a b c.
(a -> Either b c) -> Counting x b -> Counting x c -> Counting x a
choose a -> Either b c
_ (Counting Int
a) (Counting Int
b) = Int -> Counting x a
forall a b. Int -> Counting a b
Counting (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
b)