{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -Wall -Wno-name-shadowing #-} module Data.IFunctor.ICofree ( ICofree (..) ) where import Data.IComonad (IComonad (..)) import Data.IFunctor (IFunctor (..)) import Data.IFunctor.Classes import Data.ITraversable (ITraversable (..)) import Data.Typeable (Typeable) import GHC.Generics (Generic, Generic1) import Singlethongs (SingI) import Text.Read infixr 5 ::< -- | Cofree IComonad data ICofree f a ix = a ix ::< f (ICofree f a) ix deriving (Typeable, Generic, Generic1) instance IFunctor f => IFunctor (ICofree f) where imap f (a ::< x) = f a ::< imap (imap f) x instance ITraversable f => ITraversable (ICofree f) where itraverse f (a ::< x) = (::<) <$> f a <*> itraverse (itraverse f) x instance IFunctor f => IComonad (ICofree f) where iextract (a ::< _) = a iduplicate (a ::< x) = (a ::< x) ::< imap iduplicate x iextend f (a ::< x) = f (a ::< x) ::< imap (iextend f) x instance IShow f => IShow (ICofree f) where ishowsPrec sp p (a ::< x) = showParen (p > 5) $ sp 6 a . showString " ::< " . ishowsPrec (ishowsPrec sp) 6 x instance IRead f => IRead (ICofree f) where ireadPrec rp = parens $ prec 5 $ do a <- step rp Symbol "::<" <- lexP x <- step (ireadPrec (ireadPrec rp)) pure (a ::< x) instance IEq f => IEq (ICofree f) where ieq eq (a ::< x) (a' ::< x') = eq a a' && ieq (ieq eq) x x' instance IOrd f => IOrd (ICofree f) where icompare comp (a ::< x) (a' ::< x') = comp a a' <> icompare (icompare comp) x x' instance (IShow f, IShow2 a, SingI ix) => Show (ICofree f a ix) where showsPrec = ishowsPrec1 instance (IRead f, IRead2 a, SingI ix) => Read (ICofree f a ix) where readPrec = ireadPrec1 instance (IEq f, IEq2 a, SingI ix) => Eq (ICofree f a ix) where (==) = ieq1 instance (IOrd f, IOrd2 a, SingI ix) => Ord (ICofree f a ix) where compare = icompare1