{-# OPTIONS -fno-warn-orphans #-}

module Data.Function.Eq
    (
    ) where

import Data.Countable
import Data.Empty
import Data.Expression
import Data.Foldable hiding (find)
import Data.Function.Traversable ()
import Data.Searchable
import Data.Traversable
import Prelude

instance (Searchable a, Eq b) => Eq (a -> b) where
    a -> b
p == :: (a -> b) -> (a -> b) -> Bool
== a -> b
q = (a -> Bool) -> Bool
forall a. Searchable a => (a -> Bool) -> Bool
forevery (\a
a -> a -> b
p a
a b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== a -> b
q a
a)

instance (Finite a, Countable b) => Countable (a -> b) where
    countPrevious :: (a -> b) -> Maybe (a -> b)
countPrevious =
        case IsoCountable (a -> b)
forall a b. (Finite a, Countable b) => IsoCountable (a -> b)
isoCountableFn of
            MkIsoCountable (a -> b) -> l
encode l -> a -> b
decode -> ((l -> a -> b) -> Maybe l -> Maybe (a -> b)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap l -> a -> b
decode) (Maybe l -> Maybe (a -> b))
-> ((a -> b) -> Maybe l) -> (a -> b) -> Maybe (a -> b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> Maybe l
forall a. Countable a => a -> Maybe a
countPrevious (l -> Maybe l) -> ((a -> b) -> l) -> (a -> b) -> Maybe l
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> l
encode
    countMaybeNext :: Maybe (a -> b) -> Maybe (a -> b)
countMaybeNext =
        case IsoCountable (a -> b)
forall a b. (Finite a, Countable b) => IsoCountable (a -> b)
isoCountableFn of
            MkIsoCountable (a -> b) -> l
encode l -> a -> b
decode -> ((l -> a -> b) -> Maybe l -> Maybe (a -> b)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap l -> a -> b
decode) (Maybe l -> Maybe (a -> b))
-> (Maybe (a -> b) -> Maybe l) -> Maybe (a -> b) -> Maybe (a -> b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe l -> Maybe l
forall a. Countable a => Maybe a -> Maybe a
countMaybeNext (Maybe l -> Maybe l)
-> (Maybe (a -> b) -> Maybe l) -> Maybe (a -> b) -> Maybe l
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((a -> b) -> l) -> Maybe (a -> b) -> Maybe l
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> b) -> l
encode)

instance (Finite a, AtLeastOneCountable b) => AtLeastOneCountable (a -> b) where
    countFirst :: a -> b
countFirst = \a
_ -> b
forall a. AtLeastOneCountable a => a
countFirst

setpair :: (Eq a) => (a, b) -> (a -> b) -> (a -> b)
setpair :: forall a b. Eq a => (a, b) -> (a -> b) -> a -> b
setpair (a
a', b
b') a -> b
_ a
a
    | a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
a' = b
b'
setpair (a, b)
_ a -> b
ab a
a = a -> b
ab a
a

data IsoCountable x =
    forall l. (Countable l) =>
                  MkIsoCountable (x -> l)
                                 (l -> x)

isoCountableFn :: (Finite a, Countable b) => IsoCountable (a -> b)
isoCountableFn :: forall a b. (Finite a, Countable b) => IsoCountable (a -> b)
isoCountableFn = [a] -> IsoCountable (a -> b)
forall a b. (Eq a, Countable b) => [a] -> IsoCountable (a -> b)
makeFromList [a]
forall a. Finite a => [a]
allValues
  where
    makeFromList :: (Eq a, Countable b) => [a] -> IsoCountable (a -> b)
    makeFromList :: forall a b. (Eq a, Countable b) => [a] -> IsoCountable (a -> b)
makeFromList [] = ((a -> b) -> ()) -> (() -> a -> b) -> IsoCountable (a -> b)
forall x l. Countable l => (x -> l) -> (l -> x) -> IsoCountable x
MkIsoCountable (\a -> b
_ -> ()) (\()
a -> () -> (a -> b) -> a -> b
forall a b. a -> b -> b
seq ()
a a -> b
forall a. HasCallStack => a
undefined)
    makeFromList (a
a:[a]
as) =
        case [a] -> IsoCountable (a -> b)
forall a b. (Eq a, Countable b) => [a] -> IsoCountable (a -> b)
makeFromList [a]
as of
            MkIsoCountable (a -> b) -> l
encode l -> a -> b
decode ->
                ((a -> b) -> (b, l)) -> ((b, l) -> a -> b) -> IsoCountable (a -> b)
forall x l. Countable l => (x -> l) -> (l -> x) -> IsoCountable x
MkIsoCountable (\a -> b
ab -> (a -> b
ab a
a, (a -> b) -> l
encode a -> b
ab)) (\(b
b, l
l) -> (a, b) -> (a -> b) -> a -> b
forall a b. Eq a => (a, b) -> (a -> b) -> a -> b
setpair (a
a, b
b) (l -> a -> b
decode l
l))

data IsoInfiniteCountable x =
    forall l. (InfiniteCountable l) =>
                  MkIsoInfiniteCountable (x -> l)
                                         (l -> x)

isoInfiniteCountableFn :: (Finite a, AtLeastOneCountable a, InfiniteCountable b) => IsoInfiniteCountable (a -> b)
isoInfiniteCountableFn :: forall a b.
(Finite a, AtLeastOneCountable a, InfiniteCountable b) =>
IsoInfiniteCountable (a -> b)
isoInfiniteCountableFn = [a] -> IsoInfiniteCountable (a -> b)
forall a b.
(Eq a, InfiniteCountable b) =>
[a] -> IsoInfiniteCountable (a -> b)
makeFromList [a]
forall a. Finite a => [a]
allValues
  where
    makeFromList :: (Eq a, InfiniteCountable b) => [a] -> IsoInfiniteCountable (a -> b)
    makeFromList :: forall a b.
(Eq a, InfiniteCountable b) =>
[a] -> IsoInfiniteCountable (a -> b)
makeFromList [] = IsoInfiniteCountable (a -> b)
forall a. HasCallStack => a
undefined
    makeFromList [a
a] = ((a -> b) -> b) -> (b -> a -> b) -> IsoInfiniteCountable (a -> b)
forall x l.
InfiniteCountable l =>
(x -> l) -> (l -> x) -> IsoInfiniteCountable x
MkIsoInfiniteCountable (\a -> b
ab -> a -> b
ab a
a) (\b
b -> (a, b) -> (a -> b) -> a -> b
forall a b. Eq a => (a, b) -> (a -> b) -> a -> b
setpair (a
a, b
b) (\a
a' -> a -> b -> b
forall a b. a -> b -> b
seq a
a' b
forall a. HasCallStack => a
undefined))
    makeFromList (a
a:[a]
as) =
        case [a] -> IsoInfiniteCountable (a -> b)
forall a b.
(Eq a, InfiniteCountable b) =>
[a] -> IsoInfiniteCountable (a -> b)
makeFromList [a]
as of
            MkIsoInfiniteCountable (a -> b) -> l
encode l -> a -> b
decode ->
                ((a -> b) -> (b, l))
-> ((b, l) -> a -> b) -> IsoInfiniteCountable (a -> b)
forall x l.
InfiniteCountable l =>
(x -> l) -> (l -> x) -> IsoInfiniteCountable x
MkIsoInfiniteCountable (\a -> b
ab -> (a -> b
ab a
a, (a -> b) -> l
encode a -> b
ab)) (\(b
b, l
l) -> (a, b) -> (a -> b) -> a -> b
forall a b. Eq a => (a, b) -> (a -> b) -> a -> b
setpair (a
a, b
b) (l -> a -> b
decode l
l))

instance (Finite a, AtLeastOneCountable a, InfiniteCountable b) => InfiniteCountable (a -> b) where
    countNext :: Maybe (a -> b) -> a -> b
countNext =
        case IsoInfiniteCountable (a -> b)
forall a b.
(Finite a, AtLeastOneCountable a, InfiniteCountable b) =>
IsoInfiniteCountable (a -> b)
isoInfiniteCountableFn of
            MkIsoInfiniteCountable (a -> b) -> l
encode l -> a -> b
decode -> l -> a -> b
decode (l -> a -> b) -> (Maybe (a -> b) -> l) -> Maybe (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe l -> l
forall a. InfiniteCountable a => Maybe a -> a
countNext (Maybe l -> l)
-> (Maybe (a -> b) -> Maybe l) -> Maybe (a -> b) -> l
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((a -> b) -> l) -> Maybe (a -> b) -> Maybe l
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> b) -> l
encode)

instance (Finite a, Finite b) => Finite (a -> b) where
    allValues :: [a -> b]
allValues = (a -> [b]) -> [a -> b]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a. Applicative f => (a -> f a) -> f (a -> a)
sequenceA (\a
_ -> [b]
forall a. Finite a => [a]
allValues)
    assemble :: forall b (f :: * -> *).
Applicative f =>
((a -> b) -> f b) -> f ((a -> b) -> b)
assemble (a -> b) -> f b
abfr =
        Expression a ((->) b) f b -> f ((a -> b) -> b)
forall (f :: * -> *) a b r.
Functor f =>
Expression a ((->) b) f r -> f ((a -> b) -> r)
runValueExpression
            ((a
 -> ((a -> b) -> Expression a ((->) b) f b)
 -> (a -> b)
 -> Expression a ((->) b) f b)
-> ((a -> b) -> Expression a ((->) b) f b)
-> [a]
-> (a -> b)
-> Expression a ((->) b) f b
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Data.Foldable.foldr a
-> ((a -> b) -> Expression a ((->) b) f b)
-> (a -> b)
-> Expression a ((->) b) f b
forall {a} {f :: * -> *} {t} {r}.
(Finite a, Applicative f, Eq t) =>
t
-> ((t -> a) -> Expression t ((->) a) f r)
-> (t -> a)
-> Expression t ((->) a) f r
assemble1 (\a -> b
ab -> f b -> Expression a ((->) b) f b
forall a (g :: * -> *) (f :: * -> *) r. f r -> Expression a g f r
ClosedExpression ((a -> b) -> f b
abfr a -> b
ab)) [a]
forall a. Finite a => [a]
allValues (\a
_ -> [Char] -> b
forall a. HasCallStack => [Char] -> a
error [Char]
"missing value"))
      where
            -- assemble1 :: a -> ((a -> b) -> Expression a b f r) -> (a -> b) -> Expression a b f r
        assemble1 :: t
-> ((t -> a) -> Expression t ((->) a) f r)
-> (t -> a)
-> Expression t ((->) a) f r
assemble1 t
a0 (t -> a) -> Expression t ((->) a) f r
aber t -> a
x =
            t -> Expression t ((->) a) f (a -> r) -> Expression t ((->) a) f r
forall a (g :: * -> *) (f :: * -> *) r.
a -> Expression a g f (g r) -> Expression a g f r
OpenExpression
                t
a0
                ((a -> Expression t ((->) a) f r)
-> Expression t ((->) a) f (a -> r)
forall a b (f :: * -> *).
(Finite a, Applicative f) =>
(a -> f b) -> f (a -> b)
forall b (f :: * -> *). Applicative f => (a -> f b) -> f (a -> b)
assemble
                     (\a
b0 ->
                          (t -> a) -> Expression t ((->) a) f r
aber
                              (\t
a ->
                                   if t
a t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
a0
                                       then a
b0
                                       else t -> a
x t
a)))

instance (AtLeastOneCountable a, Finite a, Empty b) => Empty (a -> b) where
    never :: forall a. (a -> b) -> a
never a -> b
ab = b -> a
forall a. b -> a
forall n a. Empty n => n -> a
never (a -> b
ab a
forall a. AtLeastOneCountable a => a
countFirst)