Metamorphosis icon indicating copy to clipboard operation
Metamorphosis copied to clipboard

Generate function to transform a "smaller record" to a "larger record"?

Open saurabhnanda opened this issue 8 years ago • 1 comments

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

saurabhnanda avatar Aug 14 '17 12:08 saurabhnanda

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.

maxigit avatar Aug 14 '17 17:08 maxigit