Package maintainers and Hackage trustees are allowed to edit certain bits
of package metadata after a release, without uploading a new tarball.
Note that the tarball itself is never changed, just the metadata that is
stored separately. For more information about metadata revisions, please
refer to the
Hackage Metadata Revisions FAQ.
| No. |
Time |
User |
SHA256 |
| -r14 |
2026-06-23T23:59:44Z |
BaldurBlondal |
a3555c24e7cd4993dfeba5807edd3ce6cb09557ea544398f66a88244aa09b1e1
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's /stock/ deriving.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are synthesisable but cannot be used with @DerivingVia@ due to role
issues.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze,Silver,Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's /stock/ deriving.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,† @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@,† @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
† @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are synthesisable but cannot be used with @DerivingVia@ due to role
issues.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze,Silver,Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r13 |
2026-06-23T23:58:30Z |
BaldurBlondal |
44e3a343b66146f9e5b9827fabb5727242bc9ff35a107a5d4ccaa0c3016a68f9
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's /stock/ deriving.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are synthesisable but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's /stock/ deriving.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are synthesisable but cannot be used with @DerivingVia@ due to role
issues.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze,Silver,Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r12 |
2026-06-23T23:47:42Z |
BaldurBlondal |
d7e277752da38452046699a840d08c2f64afe753087c98f2736d1b7f009ca57a
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's /stock/ deriving.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are supported by but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's /stock/ deriving.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are synthesisable but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r11 |
2026-06-23T23:46:23Z |
BaldurBlondal |
91fad8bece98e45e441faf8bd59cfde668d20a675798263f5ec8af6fd0e00ac9
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's stock @deriving@.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are supported by but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's /stock/ deriving.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are supported by but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r10 |
2026-06-23T23:45:28Z |
BaldurBlondal |
d884764158bef91af5797218d05c2a798c5d0da6421c60fd7f4acab89d03ac39
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock
Stock> @T@ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's stock @deriving@.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are supported by but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
__@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock T>@__ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's stock @deriving@.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are supported by but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int -- (+)
> , coins :: Int -- (+)
> , poisoned :: Bool -- (||)
> , items :: Map Item Int -- unionWith (+)
> , weapons :: Map Weapon Int -- unionWith (+)
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r9 |
2026-06-23T23:44:02Z |
BaldurBlondal |
25975bdbeac8cf45bbfa728ac7ebc70128c5e0b826fdfe6aa72baaae6b23ac18
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
Synthesized instances emulate GHC's stock @deriving@: often
/byte-identical/ optimised Core, and the @Stock@ wrapper always
erases at compile time (machine-checked with @inspection-testing@).
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock
Stock> @T@ and higher-kinded variants at /compile time/, straight
from the structure of /T/ without a @Generic@ representation or
runtime cost. Synthesized instances emulate GHC's stock @deriving@.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@
are supported by but cannot be derived via.
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r8 |
2026-06-23T22:56:10Z |
BaldurBlondal |
6045f2ba61aa674977b4721b75d8182288a0051d9199a93e0a63aee99a1bebaf
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive at all) produce a @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#v:traverse traverse>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ / @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
Synthesized instances emulate GHC's stock @deriving@: often
/byte-identical/ optimised Core, and the @Stock@ wrapper always
erases at compile time (machine-checked with @inspection-testing@).
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ \/ @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r7 |
2026-06-23T22:45:43Z |
BaldurBlondal |
c590ebaa787b3acf530b4f0f5b868d86e44938a812462de726f564cbff7543e5
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@__: @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Text-Show.html#t:Show Show>@, @<https://hackage.haskell.org/package/base/docs/Text-Read.html#t:Read Read>@, @<https://hackage.haskell.org/package/base/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage.haskell.org/package/base/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage.haskell.org/package/base/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage.haskell.org/package/base/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage.haskell.org/package/base/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage.haskell.org/package/base/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage.haskell.org/package/base/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage.haskell.org/package/base/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive at all) produce a @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#v:traverse traverse>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ / @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Show.html#t:Show Show>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Text-Read.html#t:Read Read>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Enum Enum>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive at all) produce a @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#v:traverse traverse>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage-content.haskell.org/package/deepseq-1.5.2.0/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage-content.haskell.org/package/hashable-1.5.1.0/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage-content.haskell.org/package/aeson-2.3.0.0/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage-content.haskell.org/package/QuickCheck-2.18.0.0/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage-content.haskell.org/package/profunctors-5.6.3/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage-content.haskell.org/package/stock-0.1.0.0/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Foldable.html#t:Foldable Foldable>@ / @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r6 |
2026-06-23T22:37:37Z |
BaldurBlondal |
9dcb52b859816265380e1fa0c59ca8cadd7a103a7c7f1f612033a8778bbccfc0
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@__: @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Text-Show.html#t:Show Show>@, @<https://hackage.haskell.org/package/base/docs/Text-Read.html#t:Read Read>@, @<https://hackage.haskell.org/package/base/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage.haskell.org/package/base/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage.haskell.org/package/base/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage.haskell.org/package/base/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage.haskell.org/package/base/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage.haskell.org/package/base/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage.haskell.org/package/base/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage.haskell.org/package/base/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive at all) produce a @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#v:traverse traverse>@ / @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@/@<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ / @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@__: @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Text-Show.html#t:Show Show>@, @<https://hackage.haskell.org/package/base/docs/Text-Read.html#t:Read Read>@, @<https://hackage.haskell.org/package/base/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage.haskell.org/package/base/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage.haskell.org/package/base/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage.haskell.org/package/base/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage.haskell.org/package/base/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage.haskell.org/package/base/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage.haskell.org/package/base/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage.haskell.org/package/base/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive at all) produce a @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#v:traverse traverse>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ / @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r5 |
2026-06-23T22:36:28Z |
BaldurBlondal |
92dfe8482a2f0d34f75f5dd4683608dac13747edb276e84a577ef8d121e31a29
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@__: @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Text-Show.html#t:Show Show>@, @<https://hackage.haskell.org/package/base/docs/Text-Read.html#t:Read Read>@, @<https://hackage.haskell.org/package/base/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage.haskell.org/package/base/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage.haskell.org/package/base/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage.haskell.org/package/base/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage.haskell.org/package/base/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage.haskell.org/package/base/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage.haskell.org/package/base/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage.haskell.org/package/base/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive
at all) produce a @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#v:traverse traverse>@/@<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@/@<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@
reverses ordering, enumeration and bounds;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@ effects;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@/@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@__: @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Text-Show.html#t:Show Show>@, @<https://hackage.haskell.org/package/base/docs/Text-Read.html#t:Read Read>@, @<https://hackage.haskell.org/package/base/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage.haskell.org/package/base/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage.haskell.org/package/base/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage.haskell.org/package/base/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage.haskell.org/package/base/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage.haskell.org/package/base/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage.haskell.org/package/base/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage.haskell.org/package/base/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive at all) produce a @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#v:traverse traverse>@ / @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@/@<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
* @<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@ reverses ordering, enumeration and bounds
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@ reverses @<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@ effects
* @<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ / @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r4 |
2026-06-23T22:33:23Z |
BaldurBlondal |
0fd052fdf8c5960abeb6163e1b0922e43ce9f9b9add68c3b8697224bba5fda09
|
|
Changed description
from A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* @<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@: 'Eq', 'Ord', 'Show', 'Read', 'Semigroup', 'Monoid',
'Enum', 'Bounded', 'Ix', 'Generic'
* @<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@: 'Functor', 'Foldable', 'Traversable', 'Contravariant',
'Applicative', 'Eq1', 'Ord1', 'Show1', 'Read1', 'Generic1',
'TestEquality', 'TestCoercion'
* @<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@: 'Bifunctor', 'Bifoldable', 'Bitraversable', 'Eq2',
'Ord2', 'Show2', 'Read2', 'Category'
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For 'Eq', 'Ord', 'Enum', 'Functor', 'Bounded' and 'Foldable' the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* 'Traversable' and 'Bitraversable' (which GHC cannot stock-derive
at all) produce a 'traverse'/'bitraverse' /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
'Traversable'/'Bitraversable' are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* @<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* @<https://hackage.haskell.org/package/stock-hashable stock-hashable>@: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* @<https://hackage.haskell.org/package/stock-aeson stock-aeson>@: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* @<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* @<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@
reverses ordering, enumeration and bounds;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@
reverses 'Applicative' effects;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses 'Foldable'/'Traversable'.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@__: @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Text-Show.html#t:Show Show>@, @<https://hackage.haskell.org/package/base/docs/Text-Read.html#t:Read Read>@, @<https://hackage.haskell.org/package/base/docs/Data-Semigroup.html#t:Semigroup Semigroup>@, @<https://hackage.haskell.org/package/base/docs/Data-Monoid.html#t:Monoid Monoid>@,
@<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@, @<https://hackage.haskell.org/package/base/docs/Data-Ix.html#t:Ix Ix>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic Generic>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@__: @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html#t:Contravariant Contravariant>@,
@<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq1 Eq1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord1 Ord1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show1 Show1>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read1 Read1>@, @<https://hackage.haskell.org/package/base/docs/GHC-Generics.html#t:Generic1 Generic1>@,
@<https://hackage.haskell.org/package/base/docs/Data-Type-Equality.html#t:TestEquality TestEquality>@, @<https://hackage.haskell.org/package/base/docs/Data-Type-Coercion.html#t:TestCoercion TestCoercion>@
* __@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@__: @<https://hackage.haskell.org/package/base/docs/Data-Bifunctor.html#t:Bifunctor Bifunctor>@, @<https://hackage.haskell.org/package/base/docs/Data-Bifoldable.html#t:Bifoldable Bifoldable>@, @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Eq2 Eq2>@,
@<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Ord2 Ord2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Show2 Show2>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor-Classes.html#t:Read2 Read2>@, @<https://hackage.haskell.org/package/base/docs/Control-Category.html#t:Category Category>@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @<https://hackage.haskell.org/package/base/docs/Data-Eq.html#t:Eq Eq>@, @<https://hackage.haskell.org/package/base/docs/Data-Ord.html#t:Ord Ord>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Enum Enum>@, @<https://hackage.haskell.org/package/base/docs/Data-Functor.html#t:Functor Functor>@, @<https://hackage.haskell.org/package/base/docs/Prelude.html#t:Bounded Bounded>@ and @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@ and @<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ (which GHC cannot stock-derive
at all) produce a @<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#v:traverse traverse>@/@<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#v:bitraverse bitraverse>@ /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@/@<https://hackage.haskell.org/package/base/docs/Data-Bitraversable.html#t:Bitraversable Bitraversable>@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* __@<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@__: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* __@<https://hackage.haskell.org/package/stock-hashable stock-hashable>@__: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* __@<https://hackage.haskell.org/package/stock-aeson stock-aeson>@__: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* __@<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@__: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* __@<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@__: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@
reverses ordering, enumeration and bounds;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Control-Applicative.html#t:Applicative Applicative>@ effects;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses @<https://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable Foldable>@/@<https://hackage.haskell.org/package/base/docs/Data-Traversable.html#t:Traversable Traversable>@.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r3 |
2026-06-23T22:19:12Z |
BaldurBlondal |
8a2e58ed4bceb2b5acb2d877d6da3c6c5205966c4865205f68f4c822611e76be
|
|
Changed description
from A GHC type-checker plugin that derives class instances for <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock> @T@
and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>: @Eq@, @Ord@, @Show@, @Read@, @Semigroup@, @Monoid@,
@Enum@, @Bounded@, @Ix@, @Generic@
* <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>: @Functor@, @Foldable@, @Traversable@, @Contravariant@,
@Applicative@, @Eq1@, @Ord1@, @Show1@, @Read1@, @Generic1@,
@TestEquality@, @TestCoercion@
* <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>: @Bifunctor@, @Bifoldable@, @Bitraversable@, @Eq2@,
@Ord2@, @Show2@, @Read2@, @Category@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @Eq@, @Ord@, @Enum@, @Functor@, @Bounded@ and @Foldable@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @Traversable@ and @Bitraversable@ (which GHC cannot stock-derive
at all) produce a @traverse@/@bitraverse@ /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock> wrapper and
its coercions /completely/, so the instance is exactly as fast as a
hand-written one and behaves identically to stock deriving wherever
GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@Traversable@/@Bitraversable@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* <https://hackage.haskell.org/package/stock-deepseq stock-deepseq>: @NFData@, @NFData1@, @NFData2@
* <https://hackage.haskell.org/package/stock-hashable stock-hashable>: @Hashable@, @Hashable1@, @Hashable2@
* <https://hackage.haskell.org/package/stock-aeson stock-aeson>: @ToJSON@, @ToJSON1@, @ToJSON2@; @FromJSON@,
@FromJSON1@, @FromJSON2@
* <https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>: @Arbitrary@, @Arbitrary1@, @Arbitrary2@;
@CoArbitrary@
* <https://hackage.haskell.org/package/stock-profunctors stock-profunctors>: @Profunctor@
Ordinary @DerivingVia@ modifiers compose with <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
@Down (Stock T)@ reverses ordering, enumeration and bounds;
@Backwards (Stock1 F)@ reverses @Applicative@ effects; @Reverse
(Stock1 F)@ reverses @Foldable@/@Traversable@.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
Hit points and coins accumulate with addition, poisoning
contaminates by disjunction (or), @items@, and @weapons@ union with
addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>
@T@ and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* @<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@: 'Eq', 'Ord', 'Show', 'Read', 'Semigroup', 'Monoid',
'Enum', 'Bounded', 'Ix', 'Generic'
* @<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>@: 'Functor', 'Foldable', 'Traversable', 'Contravariant',
'Applicative', 'Eq1', 'Ord1', 'Show1', 'Read1', 'Generic1',
'TestEquality', 'TestCoercion'
* @<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>@: 'Bifunctor', 'Bifoldable', 'Bitraversable', 'Eq2',
'Ord2', 'Show2', 'Read2', 'Category'
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For 'Eq', 'Ord', 'Enum', 'Functor', 'Bounded' and 'Foldable' the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* 'Traversable' and 'Bitraversable' (which GHC cannot stock-derive
at all) produce a 'traverse'/'bitraverse' /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the
@<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>@
wrapper and its coercions /completely/, so the instance is exactly
as fast as a hand-written one and behaves identically to stock
deriving wherever GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
'Traversable'/'Bitraversable' are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* @<https://hackage.haskell.org/package/stock-deepseq stock-deepseq>@: @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData NFData>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData1 NFData1>@, @<https://hackage.haskell.org/package/deepseq/docs/Control-DeepSeq.html#t:NFData2 NFData2>@
* @<https://hackage.haskell.org/package/stock-hashable stock-hashable>@: @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable.html#t:Hashable Hashable>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable1 Hashable1>@, @<https://hackage.haskell.org/package/hashable/docs/Data-Hashable-Lifted.html#t:Hashable2 Hashable2>@
* @<https://hackage.haskell.org/package/stock-aeson stock-aeson>@: @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON ToJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON1 ToJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:ToJSON2 ToJSON2>@; @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON1 FromJSON1>@, @<https://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON2 FromJSON2>@
* @<https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>@: @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary Arbitrary>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary1 Arbitrary1>@, @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:Arbitrary2 Arbitrary2>@; @<https://hackage.haskell.org/package/QuickCheck/docs/Test-QuickCheck.html#t:CoArbitrary CoArbitrary>@
* @<https://hackage.haskell.org/package/stock-profunctors stock-profunctors>@: @<https://hackage.haskell.org/package/profunctors/docs/Data-Profunctor.html#t:Profunctor Profunctor>@
Ordinary @DerivingVia@ modifiers compose with
<https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
@<https://hackage-content.haskell.org/package/base-4.22.0.0/docs/Data-Ord.html#t:Down Down (Stock T)>@
reverses ordering, enumeration and bounds;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Control-Applicative-Backwards.html#t:Backwards Backwards (Stock1 F)>@
reverses 'Applicative' effects;
@<https://hackage-content.haskell.org/package/transformers-0.6.3.0/docs/Data-Functor-Reverse.html#t:Reverse Reverse (Stock1 F)>@
reverses 'Foldable'/'Traversable'.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
This game example shows hit points and coins accumulate with
addition, poisoning contaminates by disjunction (or), @items@, and
@weapons@ union with addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r2 |
2026-06-23T15:50:30Z |
BaldurBlondal |
7c2617f822b144b65b0f8819aa94f3cdc5f5cf8966c6d1931e48e988ab96f4ff
|
|
Changed description
from A GHC type-checker plugin that derives class instances for @Stock T@
and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* @Stock@: @Eq@, @Ord@, @Show@, @Read@, @Semigroup@, @Monoid@,
@Enum@, @Bounded@, @Ix@, @Generic@
* @Stock1@: @Functor@, @Foldable@, @Traversable@, @Contravariant@,
@Applicative@, @Eq1@, @Ord1@, @Show1@, @Read1@, @Generic1@,
@TestEquality@, @TestCoercion@
* @Stock2@: @Bifunctor@, @Bifoldable@, @Bitraversable@, @Eq2@,
@Ord2@, @Show2@, @Read2@, @Category@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @Eq@, @Ord@, @Enum@, @Functor@, @Bounded@ and @Foldable@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @Traversable@ and @Bitraversable@ (which GHC cannot stock-derive
at all) produce a @traverse@/@bitraverse@ /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the @Stock@ wrapper and
its coercions /completely/, so the instance is exactly as fast as a
hand-written one and behaves identically to stock deriving wherever
GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@Traversable@/@Bitraversable@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see @Stock@).
Companion packages add more classes through @DeriveStock@ instances
(see @Stock.Derive@), discovered automatically without an extra
@-fplugin@ flag:
* @stock-deepseq@: @NFData@, @NFData1@, @NFData2@
* @stock-hashable@: @Hashable@, @Hashable1@, @Hashable2@
* @stock-aeson@: @ToJSON@, @ToJSON1@, @ToJSON2@; @FromJSON@,
@FromJSON1@, @FromJSON2@
* @stock-quickcheck@: @Arbitrary@, @Arbitrary1@, @Arbitrary2@;
@CoArbitrary@
* @stock-profunctors@: @Profunctor@
Ordinary @DerivingVia@ modifiers compose with @Stock@:
@Down (Stock T)@ reverses ordering, enumeration and bounds;
@Backwards (Stock1 F)@ reverses @Applicative@ effects; @Reverse
(Stock1 F)@ reverses @Foldable@/@Traversable@.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, @Stock.Override@, re-exported by
@Stock@) customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
Hit points and coins accumulate with addition, poisoning
contaminates by disjunction (or), @items@, and @weapons@ union with
addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock> @T@
and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>: @Eq@, @Ord@, @Show@, @Read@, @Semigroup@, @Monoid@,
@Enum@, @Bounded@, @Ix@, @Generic@
* <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock1 Stock1>: @Functor@, @Foldable@, @Traversable@, @Contravariant@,
@Applicative@, @Eq1@, @Ord1@, @Show1@, @Read1@, @Generic1@,
@TestEquality@, @TestCoercion@
* <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock2 Stock2>: @Bifunctor@, @Bifoldable@, @Bitraversable@, @Eq2@,
@Ord2@, @Show2@, @Read2@, @Category@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @Eq@, @Ord@, @Enum@, @Functor@, @Bounded@ and @Foldable@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @Traversable@ and @Bitraversable@ (which GHC cannot stock-derive
at all) produce a @traverse@/@bitraverse@ /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock> wrapper and
its coercions /completely/, so the instance is exactly as fast as a
hand-written one and behaves identically to stock deriving wherever
GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@Traversable@/@Bitraversable@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see "Stock").
Companion packages add more classes through @DeriveStock@ instances
(see "Stock.Derive"), discovered automatically without an extra
@-fplugin@ flag:
* <https://hackage.haskell.org/package/stock-deepseq stock-deepseq>: @NFData@, @NFData1@, @NFData2@
* <https://hackage.haskell.org/package/stock-hashable stock-hashable>: @Hashable@, @Hashable1@, @Hashable2@
* <https://hackage.haskell.org/package/stock-aeson stock-aeson>: @ToJSON@, @ToJSON1@, @ToJSON2@; @FromJSON@,
@FromJSON1@, @FromJSON2@
* <https://hackage.haskell.org/package/stock-quickcheck stock-quickcheck>: @Arbitrary@, @Arbitrary1@, @Arbitrary2@;
@CoArbitrary@
* <https://hackage.haskell.org/package/stock-profunctors stock-profunctors>: @Profunctor@
Ordinary @DerivingVia@ modifiers compose with <https://hackage.haskell.org/package/stock/docs/Stock.html#t:Stock Stock>:
@Down (Stock T)@ reverses ordering, enumeration and bounds;
@Backwards (Stock1 F)@ reverses @Applicative@ effects; @Reverse
(Stock1 F)@ reverses @Foldable@/@Traversable@.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, "Stock.Override", re-exported by
"Stock") customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
Hit points and coins accumulate with addition, poisoning
contaminates by disjunction (or), @items@, and @weapons@ union with
addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r1 |
2026-06-23T15:33:58Z |
BaldurBlondal |
380b532c1e3a8b3ce4a4950e37f849e3c97e4b741dc0483f8063351671372a8f
|
|
Changed description
from A GHC type-checker plugin that derives class instances for @Stock T@
and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
.
Supported classes:
.
* @Stock@: Eq, Ord, Show, Read, Semigroup, Monoid, Enum, Bounded, Ix, Generic
* @Stock1@: Functor, Foldable, Traversable, Contravariant, Applicative, Eq1, Ord1, Show1, Read1, Generic1, TestEquality, TestCoercion
* @Stock2@: Bifunctor, Bifoldable, Bitraversable, Eq2, Ord2, Show2, Read2, Category
.
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
.
* For @Eq@, @Ord@, @Enum@, @Functor@, @Bounded@ and @Foldable@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @Traversable@ and @Bitraversable@ — which GHC cannot stock-derive
at all — produce a @traverse@\/@bitraverse@ /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the @Stock@ wrapper and
its coercions /completely/, so the instance is exactly as fast as a
hand-written one and behaves identically to stock deriving wherever
GHC has it.
.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
.
@Traversable@\/@Bitraversable@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see @"Stock"@).
.
Companion packages add more classes through @DeriveStock@ instances
(see @"Stock.Derive"@), discovered automatically without an extra
@-fplugin@ flag :
.
* @stock-deepseq@: NFData, NFData1, NFData2
* @stock-hashable@: Hashable, Hashable1, Hashable2
* @stock-aeson@: ToJSON, ToJSON1, ToJSON2; FromJSON, FromJSON1, FromJSON2
* @stock-quickcheck@: Arbitrary, Arbitrary1, Arbitrary2; CoArbitrary
* @stock-profunctors@: Profunctor
.
Ordinary @DerivingVia@ modifiers compose with @Stock@:
@Down (Stock T)@ reverses ordering, enumeration and bounds;
@Backwards (Stock1 F)@ reverses @Applicative@ effects; @Reverse
(Stock1 F)@ reverses @Foldable@\/@Traversable@.
.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
.
Per-field modifiers (@Override@, @"Stock.Override"@, re-exported by
@"Stock"@) customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
.
Hit points and coins accumulate with addition, poisoning
contaminates by disjunction (or), @items@, and @weapons@ union with
addition to product a multiset.
.
> import Data.Map.Monoidal (MonoidalMap(..))
> ..
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int -- these unfortunately default
> , weapons :: Map Weapon Int -- to left-biased union
> }
> deriving (Eq, Ord, Show, Read) via
> Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
.
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
to A GHC type-checker plugin that derives class instances for @Stock T@
and higher-kinded variants at /compile time/, straight from the
structure of /T/ without a @Generic@ representation or runtime cost.
Supported classes:
* @Stock@: @Eq@, @Ord@, @Show@, @Read@, @Semigroup@, @Monoid@,
@Enum@, @Bounded@, @Ix@, @Generic@
* @Stock1@: @Functor@, @Foldable@, @Traversable@, @Contravariant@,
@Applicative@, @Eq1@, @Ord1@, @Show1@, @Read1@, @Generic1@,
@TestEquality@, @TestCoercion@
* @Stock2@: @Bifunctor@, @Bifoldable@, @Bitraversable@, @Eq2@,
@Ord2@, @Show2@, @Read2@, @Category@
Every claim below is machine-checked with @inspection-testing@ (it
compares optimised Core, not behaviour):
* For @Eq@, @Ord@, @Enum@, @Functor@, @Bounded@ and @Foldable@ the
emitted Core is /byte-identical/ to GHC's own stock deriving.
* @Traversable@ and @Bitraversable@ (which GHC cannot stock-derive
at all) produce a @traverse@/@bitraverse@ /byte-identical/ to the
natural hand-written definition.
* Every remaining class is proven to erase the @Stock@ wrapper and
its coercions /completely/, so the instance is exactly as fast as a
hand-written one and behaves identically to stock deriving wherever
GHC has it.
In short: where GHC derives the class, the result is the same Core
GHC emits; where it does not, the result is the Core you would have
written by hand.
@Traversable@/@Bitraversable@ are synthesised as genuine instances
but cannot be reached by a bare @deriving via@ (the coercion is
blocked by the abstract applicative's nominal role; see @Stock@).
Companion packages add more classes through @DeriveStock@ instances
(see @Stock.Derive@), discovered automatically without an extra
@-fplugin@ flag:
* @stock-deepseq@: @NFData@, @NFData1@, @NFData2@
* @stock-hashable@: @Hashable@, @Hashable1@, @Hashable2@
* @stock-aeson@: @ToJSON@, @ToJSON1@, @ToJSON2@; @FromJSON@,
@FromJSON1@, @FromJSON2@
* @stock-quickcheck@: @Arbitrary@, @Arbitrary1@, @Arbitrary2@;
@CoArbitrary@
* @stock-profunctors@: @Profunctor@
Ordinary @DerivingVia@ modifiers compose with @Stock@:
@Down (Stock T)@ reverses ordering, enumeration and bounds;
@Backwards (Stock1 F)@ reverses @Applicative@ effects; @Reverse
(Stock1 F)@ reverses @Foldable@/@Traversable@.
> {-# options_ghc -fplugin Stock #-}
> {-# language DerivingVia #-}
>
> import Stock
> import Data.Ord (Down(..))
>
> -- >>> sort [Bronze, Silver, Gold]
> -- [Gold,Silver,Bronze]
> data Place = Bronze | Silver | Gold
> deriving (Eq, Show) via Stock Place
> deriving (Ord, Bounded, Enum) via Down (Stock Place)
Per-field modifiers (@Override@, @Stock.Override@, re-exported by
@Stock@) customise individual fields by name, type, or position; @_@
leaves a field unchanged. A modifier is any newtype with the relevant
instance.
Hit points and coins accumulate with addition, poisoning
contaminates by disjunction (or), @items@, and @weapons@ union with
addition to produce a multiset.
> import Data.Map.Monoidal (MonoidalMap(..))
>
> type MultiSet key = MonoidalMap key (Sum Int)
>
> data Inventory = Inventory
> { hp :: Int
> , coins :: Int
> , poisoned :: Bool
> , items :: Map Item Int
> , weapons :: Map Weapon Int
> }
> deriving (Eq, Ord, Show, Read) via Stock Inventory
> deriving (Semigroup, Monoid) via
> Overriding Inventory
> '[ hp via Sum
> , coins via Sum
> , poisoned via Any
> , items via MultiSet Item
> , weapons via MultiSet Weapon
> ]
Synthesis runs once per instance (not per use): @deriving Cls via Stock
T@ produces a single shared @instance Cls T@ that every call reuses.
|
| -r0 |
2026-06-23T14:40:23Z |
BaldurBlondal |
cbe838bcff3d9ea9e104ec18009010392d92f1f2f5e35b788cfff751ba83364a
|
|
|