-- | Generic reduction to normal form.
--
-- This module contains a generic function that reduces
-- a value to normal form, defined using @generics-sop@.
--
module Generics.SOP.NFData (grnf) where

import Control.DeepSeq

import Generics.SOP

-- | Generic reduction to normal form.
--
-- This function is a generic implementation of the
-- 'rnf' function that can be used to instantiate the
-- 'NFData' class in @deepseq@.
--
-- Assuming you have a 'Generics.SOP.Generic' instance
-- for your datatype @T@, you can use 'grnf' as follows:
--
-- > instance NFData T where
-- >   rnf = grnf
--
grnf :: (Generic a, All2 NFData (Code a)) => a -> ()
grnf :: forall a. (Generic a, All2 NFData (Code a)) => a -> ()
grnf = forall a. NFData a => a -> ()
rnf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k l (h :: (k -> *) -> l -> *) (xs :: l) a.
(HCollapse h, SListIN h xs) =>
h (K a) xs -> CollapseTo h a
hcollapse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} {l} (h :: (k -> *) -> l -> *) (c :: k -> Constraint)
       (xs :: l) (proxy :: (k -> Constraint) -> *) (f :: k -> *)
       (f' :: k -> *).
(AllN (Prod h) c xs, HAp h) =>
proxy c
-> (forall (a :: k). c a => f a -> f' a) -> h f xs -> h f' xs
hcliftA Proxy NFData
p (forall k a (b :: k). a -> K a b
K forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NFData a => a -> ()
rnf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. I a -> a
unI) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Generic a => a -> Rep a
from

p :: Proxy NFData
p :: Proxy NFData
p = forall {k} (t :: k). Proxy t
Proxy