{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}

module Test.MockCat.ParamDivider (ParamDivider, args, return, returnValue) where

import Test.MockCat.Cons
import Test.MockCat.Param
import Prelude hiding (return)

class ParamDivider params args return | params -> args, params -> return where
  args :: params -> args
  return :: params -> return

instance ParamDivider 
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param i :> Param r)
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param i) (Param r) where
  args :: (Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e
                 :> (Param f :> (Param g :> (Param h :> (Param i :> Param r)))))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))
args (Param a
a :> Param b
b :> Param c
c :> Param d
d :> Param e
e :> Param f
f :> Param g
g :> Param h
h :> Param i
i :> Param r
_) = Param a
a Param a
-> (Param b
    :> (Param c
        :> (Param d
            :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d
               :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))))
forall a b. a -> b -> a :> b
:> Param b
b Param b
-> (Param c
    :> (Param d
        :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))
-> Param b
   :> (Param c
       :> (Param d
           :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))))
forall a b. a -> b -> a :> b
:> Param c
c Param c
-> (Param d
    :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))
-> Param c
   :> (Param d
       :> (Param e :> (Param f :> (Param g :> (Param h :> Param i)))))
forall a b. a -> b -> a :> b
:> Param d
d Param d
-> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))
-> Param d
   :> (Param e :> (Param f :> (Param g :> (Param h :> Param i))))
forall a b. a -> b -> a :> b
:> Param e
e Param e
-> (Param f :> (Param g :> (Param h :> Param i)))
-> Param e :> (Param f :> (Param g :> (Param h :> Param i)))
forall a b. a -> b -> a :> b
:> Param f
f Param f
-> (Param g :> (Param h :> Param i))
-> Param f :> (Param g :> (Param h :> Param i))
forall a b. a -> b -> a :> b
:> Param g
g Param g -> (Param h :> Param i) -> Param g :> (Param h :> Param i)
forall a b. a -> b -> a :> b
:> Param h
h Param h -> Param i -> Param h :> Param i
forall a b. a -> b -> a :> b
:> Param i
i
  return :: (Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e
                 :> (Param f :> (Param g :> (Param h :> (Param i :> Param r)))))))))
-> Param r
return (Param a
_ :> Param b
_ :> Param c
_ :> Param d
_ :> Param e
_ :> Param f
_ :> Param g
_ :> Param h
_ :> Param i
_ :> Param r
r) = Param r
r

instance ParamDivider 
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h :> Param r)
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param h) (Param r) where
  args :: (Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e :> (Param f :> (Param g :> (Param h :> Param r))))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))
args (Param a
a :> Param b
b :> Param c
c :> Param d
d :> Param e
e :> Param f
f :> Param g
g :> Param h
h :> Param r
_) = Param a
a Param a
-> (Param b
    :> (Param c
        :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))
-> Param a
   :> (Param b
       :> (Param c
           :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))))
forall a b. a -> b -> a :> b
:> Param b
b Param b
-> (Param c
    :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))
-> Param b
   :> (Param c
       :> (Param d :> (Param e :> (Param f :> (Param g :> Param h)))))
forall a b. a -> b -> a :> b
:> Param c
c Param c
-> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))
-> Param c
   :> (Param d :> (Param e :> (Param f :> (Param g :> Param h))))
forall a b. a -> b -> a :> b
:> Param d
d Param d
-> (Param e :> (Param f :> (Param g :> Param h)))
-> Param d :> (Param e :> (Param f :> (Param g :> Param h)))
forall a b. a -> b -> a :> b
:> Param e
e Param e
-> (Param f :> (Param g :> Param h))
-> Param e :> (Param f :> (Param g :> Param h))
forall a b. a -> b -> a :> b
:> Param f
f Param f -> (Param g :> Param h) -> Param f :> (Param g :> Param h)
forall a b. a -> b -> a :> b
:> Param g
g Param g -> Param h -> Param g :> Param h
forall a b. a -> b -> a :> b
:> Param h
h
  return :: (Param a
 :> (Param b
     :> (Param c
         :> (Param d
             :> (Param e :> (Param f :> (Param g :> (Param h :> Param r))))))))
-> Param r
return (Param a
_ :> Param b
_ :> Param c
_ :> Param d
_ :> Param e
_ :> Param f
_ :> Param g
_ :> Param h
_ :> Param r
r) = Param r
r

instance ParamDivider 
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g :> Param r)
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param g) (Param r) where
  args :: (Param a
 :> (Param b
     :> (Param c
         :> (Param d :> (Param e :> (Param f :> (Param g :> Param r)))))))
-> Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))
args (Param a
a :> Param b
b :> Param c
c :> Param d
d :> Param e
e :> Param f
f :> Param g
g :> Param r
_) = Param a
a Param a
-> (Param b
    :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))
-> Param a
   :> (Param b
       :> (Param c :> (Param d :> (Param e :> (Param f :> Param g)))))
forall a b. a -> b -> a :> b
:> Param b
b Param b
-> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))
-> Param b
   :> (Param c :> (Param d :> (Param e :> (Param f :> Param g))))
forall a b. a -> b -> a :> b
:> Param c
c Param c
-> (Param d :> (Param e :> (Param f :> Param g)))
-> Param c :> (Param d :> (Param e :> (Param f :> Param g)))
forall a b. a -> b -> a :> b
:> Param d
d Param d
-> (Param e :> (Param f :> Param g))
-> Param d :> (Param e :> (Param f :> Param g))
forall a b. a -> b -> a :> b
:> Param e
e Param e -> (Param f :> Param g) -> Param e :> (Param f :> Param g)
forall a b. a -> b -> a :> b
:> Param f
f Param f -> Param g -> Param f :> Param g
forall a b. a -> b -> a :> b
:> Param g
g
  return :: (Param a
 :> (Param b
     :> (Param c
         :> (Param d :> (Param e :> (Param f :> (Param g :> Param r)))))))
-> Param r
return (Param a
_ :> Param b
_ :> Param c
_ :> Param d
_ :> Param e
_ :> Param f
_ :> Param g
_ :> Param r
r) = Param r
r

instance ParamDivider 
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f :> Param r)
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param f) (Param r) where
  args :: (Param a
 :> (Param b
     :> (Param c :> (Param d :> (Param e :> (Param f :> Param r))))))
-> Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))
args (Param a
a :> Param b
b :> Param c
c :> Param d
d :> Param e
e :> Param f
f :> Param r
_) = Param a
a Param a
-> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))
-> Param a
   :> (Param b :> (Param c :> (Param d :> (Param e :> Param f))))
forall a b. a -> b -> a :> b
:> Param b
b Param b
-> (Param c :> (Param d :> (Param e :> Param f)))
-> Param b :> (Param c :> (Param d :> (Param e :> Param f)))
forall a b. a -> b -> a :> b
:> Param c
c Param c
-> (Param d :> (Param e :> Param f))
-> Param c :> (Param d :> (Param e :> Param f))
forall a b. a -> b -> a :> b
:> Param d
d Param d -> (Param e :> Param f) -> Param d :> (Param e :> Param f)
forall a b. a -> b -> a :> b
:> Param e
e Param e -> Param f -> Param e :> Param f
forall a b. a -> b -> a :> b
:> Param f
f
  return :: (Param a
 :> (Param b
     :> (Param c :> (Param d :> (Param e :> (Param f :> Param r))))))
-> Param r
return (Param a
_ :> Param b
_ :> Param c
_ :> Param d
_ :> Param e
_ :> Param f
_ :> Param r
r) = Param r
r

instance ParamDivider 
  (Param a :> Param b :> Param c :> Param d :> Param e :> Param r)
  (Param a :> Param b :> Param c :> Param d :> Param e) (Param r) where
  args :: (Param a
 :> (Param b :> (Param c :> (Param d :> (Param e :> Param r)))))
-> Param a :> (Param b :> (Param c :> (Param d :> Param e)))
args (Param a
a :> Param b
b :> Param c
c :> Param d
d :> Param e
e :> Param r
_) = Param a
a Param a
-> (Param b :> (Param c :> (Param d :> Param e)))
-> Param a :> (Param b :> (Param c :> (Param d :> Param e)))
forall a b. a -> b -> a :> b
:> Param b
b Param b
-> (Param c :> (Param d :> Param e))
-> Param b :> (Param c :> (Param d :> Param e))
forall a b. a -> b -> a :> b
:> Param c
c Param c -> (Param d :> Param e) -> Param c :> (Param d :> Param e)
forall a b. a -> b -> a :> b
:> Param d
d Param d -> Param e -> Param d :> Param e
forall a b. a -> b -> a :> b
:> Param e
e
  return :: (Param a
 :> (Param b :> (Param c :> (Param d :> (Param e :> Param r)))))
-> Param r
return (Param a
_ :> Param b
_ :> Param c
_ :> Param d
_ :> Param e
_ :> Param r
r) = Param r
r

instance ParamDivider (Param a :> Param b :> Param c :> Param d :> Param r) (Param a :> Param b :> Param c :> Param d) (Param r) where
  args :: (Param a :> (Param b :> (Param c :> (Param d :> Param r))))
-> Param a :> (Param b :> (Param c :> Param d))
args (Param a
a :> Param b
b :> Param c
c :> Param d
d :> Param r
_) = Param a
a Param a
-> (Param b :> (Param c :> Param d))
-> Param a :> (Param b :> (Param c :> Param d))
forall a b. a -> b -> a :> b
:> Param b
b Param b -> (Param c :> Param d) -> Param b :> (Param c :> Param d)
forall a b. a -> b -> a :> b
:> Param c
c Param c -> Param d -> Param c :> Param d
forall a b. a -> b -> a :> b
:> Param d
d
  return :: (Param a :> (Param b :> (Param c :> (Param d :> Param r))))
-> Param r
return (Param a
_ :> Param b
_ :> Param c
_ :> Param d
_ :> Param r
r) = Param r
r

instance ParamDivider (Param a :> Param b :> Param c :> Param r) (Param a :> Param b :> Param c) (Param r) where
  args :: (Param a :> (Param b :> (Param c :> Param r)))
-> Param a :> (Param b :> Param c)
args (Param a
a :> Param b
b :> Param c
c :> Param r
_) = Param a
a Param a -> (Param b :> Param c) -> Param a :> (Param b :> Param c)
forall a b. a -> b -> a :> b
:> Param b
b Param b -> Param c -> Param b :> Param c
forall a b. a -> b -> a :> b
:> Param c
c
  return :: (Param a :> (Param b :> (Param c :> Param r))) -> Param r
return (Param a
_ :> Param b
_ :> Param c
_ :> Param r
r) = Param r
r

instance ParamDivider (Param a :> Param b :> Param r) (Param a :> Param b) (Param r) where
  args :: (Param a :> (Param b :> Param r)) -> Param a :> Param b
args (Param a
a :> Param b
b :> Param r
_) = Param a
a Param a -> Param b -> Param a :> Param b
forall a b. a -> b -> a :> b
:> Param b
b
  return :: (Param a :> (Param b :> Param r)) -> Param r
return (Param a
_ :> Param b
_ :> Param r
r) = Param r
r

instance ParamDivider (Param a :> Param r) (Param a) (Param r) where
  args :: (Param a :> Param r) -> Param a
args (Param a
a :> Param r
_) = Param a
a
  return :: (Param a :> Param r) -> Param r
return (Param a
_ :> Param r
r) = Param r
r

returnValue :: ParamDivider params args (Param r) => params -> r
returnValue :: forall params args r.
ParamDivider params args (Param r) =>
params -> r
returnValue = Param r -> r
forall v. Param v -> v
value (Param r -> r) -> (params -> Param r) -> params -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. params -> Param r
forall params args return.
ParamDivider params args return =>
params -> return
return