Skip to content

Instantly share code, notes, and snippets.

@cdparks
Created June 22, 2015 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cdparks/25b147d1c409a1717d48 to your computer and use it in GitHub Desktop.
Save cdparks/25b147d1c409a1717d48 to your computer and use it in GitHub Desktop.
Generic RNF
{-# LANGUAGE DeriveGeneric #-}
module Main where
import Control.DeepSeq
import Control.DeepSeq.Generics (genericRnf)
import GHC.Generics
data List a = Nil | Cons a (List a) deriving (Generic)
instance NFData a => NFData (List a) where
rnf = genericRnf
main :: IO ()
main = undefined
Building D-0.1.0.0...
Preprocessing executable 'D' for D-0.1.0.0...
[1 of 1] Compiling Main ( Main.hs, dist/build/D/D-tmp/Main.o )
==================== Derived instances ====================
Derived instances:
instance Generic (List a_a4B7) where
from Nil = M1 (L1 (M1 U1))
from (Cons g1_a4B8 g2_a4B9)
= M1 (R1 (M1 ((:*:) (M1 (K1 g1_a4B8)) (M1 (K1 g2_a4B9)))))
to (M1 (L1 (M1 U1))) = Nil
to (M1 (R1 (M1 ((:*:) (M1 (K1 g1_a4Ba)) (M1 (K1 g2_a4Bb))))))
= Cons g1_a4Ba g2_a4Bb
instance Datatype D1List where
datatypeName _ = "List"
moduleName _ = "Main"
instance Constructor C1_0List where conName _ = "Nil"
instance Constructor C1_1List where conName _ = "Cons"
Generic representation:
Generated datatypes for meta-information:
D1List
C1_0List
C1_1List
S1_1_0List
S1_1_1List
Representation types:
type Rep (List a_a4B6) = D1
D1List
(C1 C1_0List U1
:+: C1
C1_1List
(S1 NoSelector (Rec0 a_a4B6)
:*: S1 NoSelector (Rec0 (List a_a4B6))))
[1 of 1] Compiling Main ( Main.hs, dist/build/D/D-tmp/Main.o )
==================== Derived instances ====================
Derived instances:
instance Generic (List a_a4B6) where
from Nil = M1 (L1 (M1 U1))
from (Cons g1_a4B7 g2_a4B8)
= M1 (R1 (M1 ((:*:) (M1 (K1 g1_a4B7)) (M1 (K1 g2_a4B8)))))
to (M1 (L1 (M1 U1))) = Nil
to (M1 (R1 (M1 ((:*:) (M1 (K1 g1_a4B9)) (M1 (K1 g2_a4Ba))))))
= Cons g1_a4B9 g2_a4Ba
instance Datatype D1List where
datatypeName _ = "List"
moduleName _ = "Main"
instance Constructor C1_0List where conName _ = "Nil"
instance Constructor C1_1List where conName _ = "Cons"
Generic representation:
Generated datatypes for meta-information:
D1List
C1_0List
C1_1List
S1_1_0List
S1_1_1List
Representation types:
type Rep (List a_a4B5) = D1
D1List
(C1 C1_0List U1
:+: C1
C1_1List
(S1 NoSelector (Rec0 a_a4B5)
:*: S1 NoSelector (Rec0 (List a_a4B5))))
Linking dist/build/D/D ...
@cdparks
Copy link
Author

cdparks commented Jun 22, 2015

Command was
cabal build --ghc-options='-fforce-recomp -ddump-deriv -dsuppress-all'

@bitemyapp
Copy link

I think my problem is that it's not deriving the NFData instance, it's just incidental to what the genericRnf function does with the datatype representation provided by the Generic instance.

@cdparks
Copy link
Author

cdparks commented Jun 22, 2015

That makes sense, but if I run with -O0 and -ddump-simpl, I can actually see the NFData dictionary for List:

-- NFData dictionary for List
$fNFDataList
$fNFDataList = a_r4Fs `cast` ...

-- rnf for List passing NFData dictionary for element type
a_r4Fs
a_r4Fs = \ @ a1_a4wI $dNFData_a4wJ -> $crnf_r4Fr $dNFData_a4wJ

-- rnf implementation using generic representation of List
Rec {
$crnf_r4Fr
$crnf_r4Fr =
  \ @ a1_X4xm $dNFData_X4xo ->
    genericRnf
      ($fGenericList)
      (($fGNFDataM1
          ($fGNFData:+:
             ($fGNFDataM1 $fGNFDataU1)
             ($fGNFDataM1
                ($fGNFData:*:
                   ($fGNFDataM1 ($fGNFDataK1 $dNFData_X4xo))
                   ($fGNFDataM1
                      ($fGNFDataK1 (($crnf_r4Fr $dNFData_X4xo) `cast` ...)))))))
       `cast` ...)
end Rec }

Maybe it's a version difference? I'm using ghc 7.10.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment