@hackage / stock-deepseq

Derive NFData via the stock plugin

Latest0.1.0.0

About

Metadata

  • Last updated , by BaldurBlondal
  • License BSD-3-Clause
  • Categories Type System
  • Maintained by: baldur.blondal@iohk.io

  • Lottery factor: 0

Links

Installation

Tested Compilers

  1. 9.10.3
  2. 9.10.3
  3. 9.8.1

Readme

The stock plugin provides a newtype Stock for deriving and synthesising instances at compile time. stock-deepseq extends it to support NFData and higher-kinded variants.

{-# options_ghc -fplugin Stock #-}

{-# language DerivingVia #-}
{-# language DataKinds   #-}

import Stock
import Stock.NFData

import Control.Exception

data Person = P { name :: String, age :: Int, secret :: Person }
  deriving (Eq, Ord, Show, NFData) via 
    Stock Person

-- >> try @SomeException (evaluate (rnf geir))
-- Left stack overflow
-- >> geir == geir
-- <loop>
-- >> geir
-- P {name = "Geir", age = 10, secret = P {name = "Geir", .. } }
geir :: Person
geir = P { name = "Geir", age = 10, secret = geir }

The rnf function triggers the loop, but by pinning secret as an ignored field, we can happily force the other fields.

newtype Ignore a = Ignore a
instance NFData (Ignore a) where rnf _ = ()
instance Eq     (Ignore a) where _ == _ = True
instance Ord    (Ignore a) where compare _ _ = EQ
instance Show   (Ignore a) where show _ = "<ignored>"

data Person = P { name :: String, age :: Int, secret :: Person }
  deriving (Eq, Ord, Show, NFData) via 
    Overriding Person '[ secret via Ignore ]

-- >> try @SomeException (evaluate (rnf geir))
-- Right ()
-- >> geir == geir
-- True
-- >> geir
-- P {name = "Geir", age = 10, secret = <ignored>}

stock-deepseq provides three instances, that signal to the plugin how to derive NFData, NFData1, NFData2.

instance DeriveStock  NFData  ..
instance DeriveStock1 NFData1 ..
instance DeriveStock2 NFData2 ..

stock companion packages include: