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

#if __GLASGOW_HASKELL__ >= 706
{-# LANGUAGE PolyKinds            #-}
#endif

{-# OPTIONS_GHC -fno-warn-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 :: (Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Biff p f g a a -> Builder
liftShowbPrec = (Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> Biff p f g a a
-> Builder
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
forall a. TextShow a => Int -> a -> Builder
showbPrec [a] -> Builder
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 :: (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 :: (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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$
        String -> Builder
fromString String
"In {out = "
     Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Int -> Fix p a -> Builder)
-> ([Fix p a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> p (Fix p a) a
-> Builder
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)
-> ([a] -> Builder) -> Int -> Fix p a -> Builder
forall (f :: * -> *) a.
TextShow1 f =>
(Int -> a -> Builder) -> ([a] -> Builder) -> Int -> f a -> Builder
liftShowbPrec Int -> a -> Builder
sp [a] -> Builder
sl) ((Int -> a -> Builder) -> ([a] -> Builder) -> [Fix p a] -> Builder
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
     Builder -> Builder -> Builder
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 :: (Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Flip p a a -> Builder
liftShowbPrec = (Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> Flip p a a
-> Builder
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
forall a. TextShow a => Int -> a -> Builder
showbPrec [a] -> Builder
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 :: (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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$
        String -> Builder
fromString String
"Join {runJoin = "
     Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> p a a
-> Builder
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
     Builder -> Builder -> Builder
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 :: (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 :: (Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Product f g a a -> Builder
liftShowbPrec = (Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> Product f g a a
-> Builder
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
forall a. TextShow a => Int -> a -> Builder
showbPrec [a] -> Builder
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 :: (Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Sum f g a a -> Builder
liftShowbPrec = (Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> Sum f g a a
-> Builder
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
forall a. TextShow a => Int -> a -> Builder
showbPrec [a] -> Builder
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 :: (Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> Tannen f p a a -> Builder
liftShowbPrec = (Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> Tannen f p a a
-> Builder
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
forall a. TextShow a => Int -> a -> Builder
showbPrec [a] -> Builder
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 :: (Int -> a -> Builder)
-> ([a] -> Builder) -> Int -> WrappedBifunctor p a a -> Builder
liftShowbPrec = (Int -> a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Builder)
-> ([a] -> Builder)
-> Int
-> WrappedBifunctor p a a
-> Builder
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
forall a. TextShow a => Int -> a -> Builder
showbPrec [a] -> Builder
forall a. TextShow a => [a] -> Builder
showbList