{-# language CPP #-}
{-# language DataKinds #-}
{-# language DefaultSignatures #-}
{-# language FlexibleContexts #-}
{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language PolyKinds #-}
{-# language ScopedTypeVariables #-}
{-# language TypeInType #-}
{-# language TypeOperators #-}
{-# language UndecidableInstances #-}
{-# OPTIONS_HADDOCK not-home #-}
module Data.Lazify.Generic.Internal (
LazifiableG (..)
, IsNewtypeG (..)
, lazifyGeneric
, ($~)
) where
import GHC.Generics
import GHC.Exts (TYPE)
class LazifiableG f where
lazifyG :: f a -> f a
lazifyGeneric :: (Generic a, LazifiableG (Rep a)) => a -> a
lazifyGeneric = to . lazifyG . from
($~) :: forall rep a (b :: TYPE rep). (Generic a, LazifiableG (Rep a)) => (a -> b) -> a -> b
f $~ a = f (lazifyGeneric a)
instance LazifiableG f => LazifiableG (D1 ('MetaData x y z 'False) f) where
lazifyG (M1 x) = M1 (lazifyG x)
instance LazifiableG f => LazifiableG (C1 c f) where
lazifyG (M1 x) = M1 (lazifyG x)
instance LazifiableG f => LazifiableG (S1 c f) where
lazifyG (M1 x) = M1 (lazifyG x)
instance IsNewtypeG f => LazifiableG (D1 ('MetaData x y z 'True) f) where
lazifyG (M1 x) = M1 (lazifyNewtypeG x)
instance LazifiableG (K1 i c) where
lazifyG x = x
instance LazifiableG U1 where
lazifyG _ = U1
instance (LazifiableG f, LazifiableG g) => LazifiableG (f :*: g) where
lazifyG ~(x :*: y) = lazifyG x :*: lazifyG y
class IsNewtypeG f where
lazifyNewtypeG :: f a -> f a
instance IsNewtypeG f => IsNewtypeG (M1 i c f) where
lazifyNewtypeG (M1 x) = M1 (lazifyNewtypeG x)
instance (Generic a, LazifiableG (Rep a)) => IsNewtypeG (K1 i a) where
lazifyNewtypeG (K1 a) = K1 (to . lazifyG . from $ a)