Kwarrtz
Kwarrtz

Reputation: 2753

Template Haskell Function for Record Accessor Inheritance

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 As and Bs, 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

Answers (1)

MCH
MCH

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

Related Questions