module Data.Curry where

data Uncurry f ab where Uncurry :: { Uncurry f '(a, b) -> f a b
reCurry :: f a b } -> Uncurry f '(a, b)

deriving instance Eq (f a b) => Eq (Uncurry f '(a, b))
deriving instance Ord (f a b) => Ord (Uncurry f '(a, b))
deriving instance Read (f a b) => Read (Uncurry f '(a, b))
deriving instance Show (f a b) => Show (Uncurry f '(a, b))

instance Bounded (f a b) => Bounded (Uncurry f '(a, b)) where
    minBound :: Uncurry f '(a, b)
minBound = f a b -> Uncurry f '(a, b)
forall k k (f :: k -> k -> *) (a :: k) (b :: k).
f a b -> Uncurry f '(a, b)
Uncurry f a b
forall a. Bounded a => a
minBound
    maxBound :: Uncurry f '(a, b)
maxBound = f a b -> Uncurry f '(a, b)
forall k k (f :: k -> k -> *) (a :: k) (b :: k).
f a b -> Uncurry f '(a, b)
Uncurry f a b
forall a. Bounded a => a
maxBound

instance Semigroup (f a b) => Semigroup (Uncurry f '(a, b)) where
    Uncurry x :: f a b
x <> :: Uncurry f '(a, b) -> Uncurry f '(a, b) -> Uncurry f '(a, b)
<> Uncurry y :: f a b
y = f a b -> Uncurry f '(a, b)
forall k k (f :: k -> k -> *) (a :: k) (b :: k).
f a b -> Uncurry f '(a, b)
Uncurry (f a b
x f a b -> f a b -> f a b
forall a. Semigroup a => a -> a -> a
<> f a b
f a b
y)

instance Monoid (f a b) => Monoid (Uncurry f '(a, b)) where
    mempty :: Uncurry f '(a, b)
mempty = f a b -> Uncurry f '(a, b)
forall k k (f :: k -> k -> *) (a :: k) (b :: k).
f a b -> Uncurry f '(a, b)
Uncurry f a b
forall a. Monoid a => a
mempty
    Uncurry x :: f a b
x mappend :: Uncurry f '(a, b) -> Uncurry f '(a, b) -> Uncurry f '(a, b)
`mappend` Uncurry y :: f a b
y = f a b -> Uncurry f '(a, b)
forall k k (f :: k -> k -> *) (a :: k) (b :: k).
f a b -> Uncurry f '(a, b)
Uncurry (f a b
x f a b -> f a b -> f a b
forall a. Monoid a => a -> a -> a
`mappend` f a b
f a b
y)

data Curry f a b where Curry :: { Curry f a b -> f '(a, b)
unCurry :: f '(a, b) } -> Curry f a b