2

I have a large type hierarchy in Haskell. Counting family instances, which (can) have separate class membership after all, there are hundreds of data types.

Since the top-most type needs to implement built-in classes like Generic,Eq,Ord,Show, every single type in the hierarchy has to as well for a meaningful implementation overall. So my specification contains hundreds of times deriving (Generic,Eq,Ord,Show), which I would like to avoid cluttering the files.

A solution involving a single typeclass to attach everywhere like deriving GEOS with a single automatic derivation from that to the usual set in a centralized place would already help a lot with readability.

Another question asking for similar conciseness in constraints is solved by using constraint synonyms (so my GEOS would be not just linked to but explicitly made up of exactly the classes I want), which however apparently are currently prevented from being instantiated.

(A side question of mine would be why that is so. It seems to me like the reason @simonpj gives about the renamer not knowing what the type checker knows the synonym really to be would only apply to explicitly written out instance implementations.)

Maybe GHC.Generic itself (and something like generic-deriving) could help here?

Leif Willerts
  • 205
  • 1
  • 9

1 Answers1

1

You could of course use Template Haskell, to generate the deriving-clauses as -XStandaloneDeriving.

{-# LANGUAGE QuasiQuotes #-}

module GEOSDerive where

import Language.Haskell.TH
import Control.Monad
import GHC.Generics

deriveGEOS :: Q Type -> DecsQ
deriveGEOS t = do
   t' <- t
   forM [ [t|Generic|], [t|Eq|], [t|Ord|], [t|Show|] ] $ \c -> do
      c' <- c
      return $ StandaloneDerivD Nothing [] (AppT c' t')

Then,

{-# LANGUAGE TemplateHaskell, StandaloneDeriving, QuasiQuotes, DeriveGeneric #-}

import GEOSDerive

data Foo = Foo

deriveGEOS [t|Foo|]

But, I find it somewhat dubious that you need so many types in the first place, or rather that you have so many types but each of them has so little code associated with it that you're bothered about mentioning those four classes for each of them. It's not like there's anything to be concerned about regarding refactoring or so with those, so I'd rather recommend simply keeping with deriving (Generic, Eq, Ord, Show) for each of them.

leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
  • I anticipated the doubt about the structure. I'm representing a significant, domain-specific subset of the English language syntactically. Wouldn't representing for example the syntax of a programming language like Haskell (for a parser or interpreter of some kind) also involve hundreds of types? – Leif Willerts Jun 11 '20 at 21:56
  • And yes, using this type hierarchy will involve substantial amounts of code (although merely parsing and printing out is already quite a useful feature in my estimation, there's of course more to do with it). But the specification itself is about 50KB of code right now with those derivations taking a cool 4K alone. Maybe my instinct for keeping the model separate from business logic is flawed? – Leif Willerts Jun 11 '20 at 22:08
  • 1
    @LeifWillerts It is nowhere near hundreds. It looks like there are around 1400 types used in the GHC Haskell compiler total (`data`s and `newtype`s). Almost none of them are related to representing the syntax of Haskell. Many of them are related to type checking, the module system, the package system, FFI, type classes, type families, various intermediate representations, code generators, various settings, etc. I would think less than 10 are for the purpose of representing Haskell syntax. Less if you only count the user-facing language syntax (and not Core, etc). Why would you think hundreds? – David Young Jun 12 '20 at 00:45
  • I would think the majority of the representation of Haskell syntax (as in, types whose purpose is solely to directly represent parts of the Haskell AST) is contained in just a handful of types, like [this one](https://hackage.haskell.org/package/ghc-8.10.1/docs/GHC-Hs-Expr.html#t:HsExpr). – David Young Jun 12 '20 at 00:50
  • @David thanks! wouldn't have known well where to look. I guess those types tend to be more complex but less numerous, yes - though I also have a few with dozens of constructors. I am representing something natural-language-like though, and even my cursory experience with linguistic papers suggests there's just a lot of kinds of elements and sub-elements of sentences. But on top of that, yes this domain requires an inordinate amount of types, which relate to what specifically this subset of the English language is used to refer to... – Leif Willerts Jun 12 '20 at 00:57