{-# LANGUAGE FlexibleContexts     #-}
{-# LANGUAGE PolyKinds            #-}
{-# LANGUAGE TemplateHaskell      #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_GHC -Wno-orphans #-}

{-|
Module:      TextShow.Data.Bifunctor
Copyright:   (C) 2014-2017 Ryan Scott
License:     BSD-style (see the file LICENSE)
Maintainer:  Ryan Scott
Stability:   Provisional
Portability: GHC

'TextShow' instances for data types in the @bifunctors@ library.

/Since: 2/
-}
module TextShow.Data.Bifunctor () where

import Data.Bifunctor.Biff (Biff)
import Data.Bifunctor.Clown (Clown)
import Data.Bifunctor.Fix (Fix(..))
import Data.Bifunctor.Flip (Flip)
import Data.Bifunctor.Join (Join(..))
import Data.Bifunctor.Joker (Joker)
import Data.Bifunctor.Product (Product)
import Data.Bifunctor.Sum (Sum)
import Data.Bifunctor.Tannen (Tannen)
import Data.Bifunctor.Wrapped (WrappedBifunctor)

import GHC.Show (appPrec)

import Prelude ()
import Prelude.Compat

import TextShow (TextShow(..), TextShow1(..), TextShow2(..),
                 fromString, showbParen, singleton)
import TextShow.TH (deriveTextShow2, makeShowbPrec, makeLiftShowbPrec)

-- | /Since: 2/
$(deriveTextShow2 ''Biff)
-- | /Since: 2/
instance TextShow (p (f a) (g b)) => TextShow (Biff p f g a b) where
    showbPrec :: Int -> Biff p f g a b -> Builder
showbPrec = $(makeShowbPrec ''Biff)
-- | /Since: 2/
instance (TextShow2 p, TextShow1 f, TextShow1 g, TextShow a) => TextShow1 (Biff p f g a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Biff p f g a a -> Builder
liftShowbPrec = forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 forall a. TextShow a => Int -> a -> Builder
showbPrec forall a. TextShow a => [a] -> Builder
showbList

-- | /Since: 2/
instance TextShow (f a) => TextShow (Clown f a b) where
    showbPrec :: Int -> Clown f a b -> Builder
showbPrec = $(makeShowbPrec ''Clown)
-- | /Since: 2/
instance TextShow (f a) => TextShow1 (Clown f a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Clown f a a -> Builder
liftShowbPrec = $(makeLiftShowbPrec ''Clown)
-- | /Since: 2/
$(deriveTextShow2 ''Clown)

-- | /Since: 2/
instance TextShow (p (Fix p a) a) => TextShow (Fix p a) where
    showbPrec :: Int -> Fix p a -> Builder
showbPrec = $(makeShowbPrec ''Fix)
-- | /Since: 2/
instance TextShow2 p => TextShow1 (Fix p) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Fix p a -> Builder
liftShowbPrec Int -> a -> Builder
sp [a] -> Builder
sl Int
p (In p (Fix p a) a
x) = Bool -> Builder -> Builder
showbParen (Int
p forall a. Ord a => a -> a -> Bool
> Int
appPrec) forall a b. (a -> b) -> a -> b
$
        String -> Builder
fromString String
"In {out = "
     forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 (forall (f :: * -> *) a.
TextShow1 f =>
(Int -> a -> Builder) -> ([a] -> Builder) -> Int -> f a -> Builder
liftShowbPrec Int -> a -> Builder
sp [a] -> Builder
sl) (forall (f :: * -> *) a.
TextShow1 f =>
(Int -> a -> Builder) -> ([a] -> Builder) -> [f a] -> Builder
liftShowbList Int -> a -> Builder
sp [a] -> Builder
sl) Int -> a -> Builder
sp [a] -> Builder
sl Int
0 p (Fix p a) a
x
     forall a. Semigroup a => a -> a -> a
<> Char -> Builder
singleton Char
'}'

-- | /Since: 2/
$(deriveTextShow2 ''Flip)
-- | /Since: 2/
instance TextShow (p b a) => TextShow (Flip p a b) where
    showbPrec :: Int -> Flip p a b -> Builder
showbPrec = $(makeShowbPrec ''Flip)
-- | /Since: 2/
instance (TextShow2 p, TextShow a) => TextShow1 (Flip p a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Flip p a a -> Builder
liftShowbPrec = forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 forall a. TextShow a => Int -> a -> Builder
showbPrec forall a. TextShow a => [a] -> Builder
showbList

-- | /Since: 2/
instance TextShow (p a a) => TextShow (Join p a) where
    showbPrec :: Int -> Join p a -> Builder
showbPrec = $(makeShowbPrec ''Join)
-- | /Since: 2/
instance TextShow2 p => TextShow1 (Join p) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Join p a -> Builder
liftShowbPrec Int -> a -> Builder
sp [a] -> Builder
sl Int
p (Join p a a
x) = Bool -> Builder -> Builder
showbParen (Int
p forall a. Ord a => a -> a -> Bool
> Int
appPrec) forall a b. (a -> b) -> a -> b
$
        String -> Builder
fromString String
"Join {runJoin = "
     forall a. Semigroup a => a -> a -> a
<> forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 Int -> a -> Builder
sp [a] -> Builder
sl Int -> a -> Builder
sp [a] -> Builder
sl Int
0 p a a
x
     forall a. Semigroup a => a -> a -> a
<> Char -> Builder
singleton Char
'}'

-- | /Since: 2/
instance TextShow (g b) => TextShow (Joker g a b) where
    showbPrec :: Int -> Joker g a b -> Builder
showbPrec = $(makeShowbPrec ''Joker)
-- | /Since: 2/
instance TextShow1 g => TextShow1 (Joker g a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Joker g a a -> Builder
liftShowbPrec = $(makeLiftShowbPrec ''Joker)
-- | /Since: 2/
$(deriveTextShow2 ''Joker)

-- | /Since: 2/
$(deriveTextShow2 ''Product)
-- | /Since: 2/
instance (TextShow (f a b), TextShow (g a b)) => TextShow (Product f g a b) where
    showbPrec :: Int -> Product f g a b -> Builder
showbPrec = $(makeShowbPrec ''Product)
-- | /Since: 2/
instance (TextShow2 f, TextShow2 g, TextShow a) => TextShow1 (Product f g a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Product f g a a -> Builder
liftShowbPrec = forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 forall a. TextShow a => Int -> a -> Builder
showbPrec forall a. TextShow a => [a] -> Builder
showbList

-- | /Since: 2/
$(deriveTextShow2 ''Sum)
-- | /Since: 2/
instance (TextShow (f a b), TextShow (g a b)) => TextShow (Sum f g a b) where
    showbPrec :: Int -> Sum f g a b -> Builder
showbPrec = $(makeShowbPrec ''Sum)
-- | /Since: 2/
instance (TextShow2 f, TextShow2 g, TextShow a) => TextShow1 (Sum f g a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Sum f g a a -> Builder
liftShowbPrec = forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 forall a. TextShow a => Int -> a -> Builder
showbPrec forall a. TextShow a => [a] -> Builder
showbList

-- | /Since: 2/
$(deriveTextShow2 ''Tannen)
-- | /Since: 2/
instance TextShow (f (p a b)) => TextShow (Tannen f p a b) where
    showbPrec :: Int -> Tannen f p a b -> Builder
showbPrec = $(makeShowbPrec ''Tannen)
-- | /Since: 2/
instance (TextShow1 f, TextShow2 p, TextShow a) => TextShow1 (Tannen f p a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Tannen f p a a -> Builder
liftShowbPrec = forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 forall a. TextShow a => Int -> a -> Builder
showbPrec forall a. TextShow a => [a] -> Builder
showbList

-- | /Since: 2/
$(deriveTextShow2 ''WrappedBifunctor)
-- | /Since: 2/
instance TextShow (p a b) => TextShow (WrappedBifunctor p a b) where
    showbPrec :: Int -> WrappedBifunctor p a b -> Builder
showbPrec = $(makeShowbPrec ''WrappedBifunctor)
-- | /Since: 2/
instance (TextShow2 p, TextShow a) => TextShow1 (WrappedBifunctor p a) where
    liftShowbPrec :: forall a.
(Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> WrappedBifunctor p a a -> Builder
liftShowbPrec = forall (f :: * -> * -> *) a b.
TextShow2 f =>
(Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> b -> Builder)
-> ([b] -> Builder)
-> Int
-> f a b
-> Builder
liftShowbPrec2 forall a. TextShow a => Int -> a -> Builder
showbPrec forall a. TextShow a => [a] -> Builder
showbList