Reputation: 2753
I have two datatypes, A
and B
, which I have defined as:
data A = A { aFoo :: Int, aBar :: String }
data B = B { bFoo :: Int, bBar :: String, bBaz :: Float }
I now need to create a heterogeneous list of A
s and B
s, so I define a sum type, C
, as:
data C = CA A | CB B
I would now like to define the functions
cFoo :: C -> Int
cBar :: C -> String
This can be achieved with pattern matching...
cFoo (CA a) = aFoo a
cFoo (CB b) = bFoo b
cBar (CA a) = aBar a
cBar (CB b) = bBar b
...but this becomes tedious with data types of many fields. I was wondering if there is a simple solution using template Haskell, or if it wouldn't be worth the effort. I have intermediate knowledge of Haskell, but am relatively new to Template Haskell. Any help is appreciated.
Upvotes: 0
Views: 120
Reputation: 2214
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data A =
A
{ _aFoo :: Int
, _aBar :: String
}
data B =
B
{ _bFoo :: Int
, _bBar :: String
, _bBaz :: Float
}
makeLenses ''A
makeLenses ''B
data C
= CA A
| CB B
makePrisms ''C
That will give you seven functions: aFoo
, aBar
, bFoo
, bBar
, bBaz
, _CA
and _CB
.
I suggest you read this tutorial: lens over tea #6: Template Haskell.
Upvotes: 1