[Haskell-cafe] generic way to construct and deconstruct a newtype

PICCA Frederic-Emmanuel frederic-emmanuel.picca at synchrotron-soleil.fr
Tue Mar 1 10:54:02 UTC 2022


Hello, I try to write some code use to parse an ini file
for one of my softwares, using config-ini[1].

In this config file I have scientific values with units, meter, angstrom, degrees, etc...
So I created a bunch of newtype in order to deal with this part of the config file

newtype Meter = Meter (Length Double)
  deriving (Eq, Show)

newType Angstrom = Angstrom (Length Double)

[...]

Then I created a typeclasse in order to have a generic way to extract the fileds values using the BiDir api [2]

class HasFieldValue a where
  fieldvalue :: FieldValue a

instance HasFieldValue Meter where
  fieldvalue = FieldValue 
    { fvParse =  mapRight (Meter . (*~ meter)) . fvParse auto
    , fvEmit = \(Meter m) -> pack . show . (/~ meter) $ m
    }

instance HasFieldValue Angstrom where
  fieldvalue = FieldValue 
    { fvParse =  mapRight (Meter . (*~ angstrom)) . fvParse auto
    , fvEmit = \(Angstrom m) -> pack . show . (/~ angstrom) $ m
    }


I would like to factorize via a method which should take at least an unit, in order to avoid repetition.

I started with this sort of funtion, but I do not know how to write something generic for <???>

numberUnit :: (Num a, Fractional a, Read a, Show a, Typeable a) =>
             Unit m d a -> FieldValue (Quantity d a)
numberUnit u = FieldValue
  { fvParse = mapRight (<???> . (*~ u)) . fvParse number'
  , fvEmit = \(<???> v) -> pack . show . (/~ u) $ v
  }

thanks for your help


[1] https://hackage.haskell.org/package/config-ini-0.2.4.0
[2] https://hackage.haskell.org/package/config-ini-0.2.4.0/docs/Data-Ini-Config-Bidir.html


More information about the Haskell-Cafe mailing list