Guide
Using DerivingVia to Reuse Typeclass Instances in Haskell
Learn how Haskell’s DerivingVia extension lets you derive typeclass instances for newtypes by reusing instances of a representationally equal type, with a concrete MinInt example and verification steps.
Published by Tasadduq Burney
28 Jan 2026, 09:53 UTC
2 min15.3K views0

Why DerivingVia matters
DerivingVia lets you obtain instances for a newtype by reusing the instances of another type that is representationally equal (coercible). This avoids writing boilerplate instance definitions when the newtype merely wraps an existing type.
Worked example: MinInt via Min
{-# LANGUAGE DerivingVia #-}
import Data.Semigroup (Semigroup(..), Min(..))
import Data.Monoid (Monoid(..))
newtype MinInt = MinInt Int
deriving (Semigroup, Monoid) via (Min Int)
-- Example usage
example :: MinInt
example = MinInt 3 <> MinInt 4 -- uses Semigroup of Min Int
The derived Semigroup instance for MinInt forwards to the Min Int instance, so example evaluates to MinInt (Min 4). You can confirm this with getMin:
getMin (getMin example) -- yields 4
Requirements and limits
- GHC version 8.6 or later.
- Enable the extension with
{-# LANGUAGE DerivingVia #-}or the flag-XDerivingVia. - The newtype must be representationally equal to the via‑type (i.e.,
Coercible newtype via-typeholds). - Only types that already have the desired instances for the via‑type can be derived; otherwise you get a missing‑instance error.
- DerivingVia does not work for GADTs, data types with multiple constructors, or types whose runtime representation differs from the via‑type.
Common mistakes
- Forgetting to enable the extension – the compiler will reject the
viaclause. - Applying DerivingVia to a regular data type with several constructors; the coercibility check fails.
- Choosing a via‑type that lacks the needed class instance (e.g., trying to derive
Showvia a type without aShowinstance). - Assuming the derived instance behaves exactly like the wrapper type’s instance when the via‑type uses a different semantic (e.g., using
Maxinstead ofMinwhen you need the opposite ordering).
How to verify it works
- Check GHC version: run
ghc --versionand ensure it is 8.6 or newer. - Compile the module with the extension enabled (via the pragma or Cabal/stack flag).
- Load the module in GHCi and evaluate an expression that uses the derived class, e.g.
let x = MinInt 3 <> MinInt 4thengetMin (getMin x)should return4.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.