Generate function to transform a "smaller record" to a "larger record"?
Going by this example would it be possible to generate the following function via TH:
iStyleToProduct :: Style -> String -> Int -> Product
iStyleToProduct style variation qty = undefined -- will be auto-generated via TH
There is the following comment in the example, but it is quite possible that one doesn't have the notion of a "default product".
You can easily create your own StyleToProduct function by setting default product : iStyleToProduct = iProduct'StyleToProduct myDefaultProduct
At the moment, Metamorphosis doesn't deal with plain type (like Int and String), but I can see 3 ways to solve the problem.
The easiest would be to define it manually using the iStyle'ProductToProduct function
iStyleToProduct style variation qty = iStyleProductToProduct style product where
product = Product undefined variation undefined quantity
Not really elegant, but probably the simplest at the moment.
Another way, is to create two type wrapper for variation in quantity. You can do so with the following code
$(metamorphosis
( (\fd -> if fd ^. fdFieldName `elem` map Just ["variation", "quantity"]
then [fd & fdTConsName .~ capitalize (fromJust (fd ^. fdFieldName))]
else [fd & fdTConsName .~ "Style" ])
)
[''Product]
(\n -> if n `elem` ["ProductToStyle", "Product'StyleToProduct", "Quantity'Style'VariatioinToProduct"]
then (Just identityBCR)
else (Just applicativeBCR)
)
(const [''Show, ''Eq])
)
We modified slightly the field mapping function to map quantity and variation to Quantity and Variation.
This generates
data Quantity = Quantity {quantity :: Int}
deriving (Show, Eq)
data Variation = Variation {variation :: String ?
deriving (Show, Eq)
but also iQuantity'Style'VariationToProduct (arguments are in alphabetic order) which (pretty much) what you need. You'll obviously need to wrap your Int and String into Quantity and Variation but I thing it's cleaner.
The third way, is to use aStyleToProduct, which already exists but needs some default value for the missing arguments. Those default values be created by adding the appropriate instance to ConvertA . You can avoid orphan instances by creating your own type wrapper around Identity.