{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall -Wno-name-shadowing #-}
module Data.ITraversable
( ITraversable (..)
, imapDefault
-- * Re-exports
, module Data.IFunctor
) where
import Data.Functor.Identity (Identity (Identity, runIdentity))
import Data.Functor.Product (Product (Pair))
import Data.Functor.Sum (Sum (InL, InR))
import Data.IFunctor
import Singlethongs (SingI)
class IFunctor f => ITraversable f where
itraverse :: (Applicative m, SingI ix)
=> (forall ix. SingI ix => a ix -> m (b ix))
-> f a ix
-> m (f b ix)
-- | Default 'imap' for deriving 'IFunctor'
imapDefault :: ITraversable f
=> (a ~~> b)
-> (f a ~~> f b)
imapDefault f = runIdentity . itraverse (Identity . f)
instance ITraversable (Sum a) where
itraverse _ (InL x) = pure $ InL x
itraverse f (InR x) = InR <$> f x
instance ITraversable (Product a) where
itraverse f (Pair a b) = Pair a <$> f b