2

I have a module Foo.hs which contains a definition which does not derive Generic:

-- Foo.hs
data Blather = Blather ...  -- Generic not derived here

And in another module I want to derive ToJSON:

-- Bar.hs
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}

import GHC.Generics
import Data.Aeson

instance Generic Blather
instance ToJSON Blather

but it doesn't compile. If I derive Generic in Foo.hs at the definition site I can later derive ToJSON in another module.

Can I derive ToJSON Blather in Bar.hs without modifying the original Foo.hs?

Or is there a simple way to write instance ToJSON Blather by hand?

Shaun the Sheep
  • 22,353
  • 1
  • 72
  • 100
ErikR
  • 51,541
  • 9
  • 73
  • 124
  • Does it work with the [`StandaloneDeriving` extension](https://downloads.haskell.org/~ghc/7.8.4/docs/html/users_guide/deriving.html)? – Shaun the Sheep Aug 08 '17 at 15:41
  • Why don't you want to derive `Generic` where you define the type? Orphan instances are evil! – dfeuer Aug 08 '17 at 18:29
  • Yes, that would be the right solution, but at this point in time I don't want to submit a PR which modifies `Foo.hs`. – ErikR Aug 08 '17 at 18:35

1 Answers1

4

Enable StandaloneDeriving and use deriving instance ... since this doesn't require that the derivation is in the same module as the data type.

Example:

{-# LANGUAGE DeriveGeneric, StandaloneDeriving, DeriveAnyClass #-}

import GHC.Generics
import Data.Aeson
import Foo

deriving instance Generic Blather
deriving instance ToJSON Blather

main = undefined
Shaun the Sheep
  • 22,353
  • 1
  • 72
  • 100
  • Ah - I was following the recipe [here](https://artyom.me/aeson#records-and-json-generics) and just used `instance ...` not `deriving instance`. – ErikR Aug 08 '17 at 17:09
  • 3
    @ErikR Giving an empty instance declaration works for `ToJSON`, but not for `Generic`. The reasons are a bit subtle: `Generic` is a class for which deriving is built-in. `ToJSON` is a class for which generic "default signatures" and implementations are given. – kosmikus Aug 09 '17 at 19:09