Reputation: 3428
My program is using Uniplate.Data extensively, and want to improve its performance.
Currently I'm deriving Data
instances automatically using the DeriveDataTypeable
GHC extension.
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Generics.Uniplate.Data
data Expr = Val Int
| Neg Expr
| Add Expr Expr
deriving (Data,Typeable)
The Uniplate.Data package description recommend using Uniplate.Direct because of superior performance.
The latter requires writing explicit Uniplate
instances for data types, and recommend the Derive tool for that.
When trying to derive instances automatically using Derive
:
{-# LANGUAGE TemplateHaskell #-}
import Data.DeriveTH
import Data.Generics.Uniplate.Direct
data Expr = Val Int
| Neg Expr
| Add Expr Expr
$( derive makeUniplateDirect ''Expr )
I get the following error:
Exception when trying to run compile-time code:
Derivation of UniplateDirect does not yet support Template Haskell, requires info for Expr
Code: derive makeUniplateDirect ''Expr
Is there any other way of deriving Uniplate.Direct
instances automatically?
Thanks!
Upvotes: 1
Views: 239
Reputation: 27636
As the error message says, UniplateDirect
doesn't support TH mode of derive
, so you have to use the standalone executable version as a preprocessor to generate the Uniplate
instance.
You can do this by adding {-! !-}
directives, and setting derive
as a preprocessor to be run by GHC:
{-# OPTIONS_GHC -F -pgmFderive -optF-F #-}
import Data.Generics.Uniplate.Direct
data Expr = Val Int
| Neg Expr
| Add Expr Expr
{-!
deriving instance UniplateDirect Expr
!-}
Loading this into GHCi for a quick test confirms you have your instance:
[1 of 1] Compiling Main ( SO31725183.hs, interpreted )
Ok, modules loaded: Main.
*Main> :i Expr
data Expr = Val Int | Neg Expr | Add Expr Expr
-- Defined at D:\cygwin\tmp\ghc13224_0\ghc13224_3.hspp:6:1
instance Uniplate Expr
-- Defined at D:\cygwin\tmp\ghc13224_0\ghc13224_3.hspp:16:10
Upvotes: 2