0

I have a specific set of functions of type Function which I want to be able to store to and parse from disk. So I create a helper data type FunctionData like so

data Function = Function {..., functionToFunctionData :: FunctionData}

fFun :: Some -> Weird -> Arguments -> Function
fFun a b c = ...

gFun :: And -> Other -> Probably -> More -> Complicated -> Arguments -> Function
gFun a b c d e f = ...

data FunctionData = FFun Some Weird Arguments
                    | GFun And Other Probably More Complicated Arguments
$(deriveJSON defaultOptions ''FunctionData)

functionDataToFunction :: FunctionData -> Function
functionDataToFunction (FFun a b c) = fFun a b c
functionDataToFunction (GFun a b c d e f) = gFun a b c d e f

Now, I have a bijective map between Function and FunctionData, that is

functionDataToFunction . functionToFunctionData = id
functionToFunctionData . functionDataToFunction = id

and so, I can store and parse Functions to and from disk.

instance ToJSON Function where
  toJSON = toJSON . functionToFunctioData

instance FromJSON Function where
  parseJSON v = functionDataToFunction <$> parseJSON v

Now, I have a lot of those functions, and I also sometimes change them. Is there a way to automate this process (at least somewhat)? Most importantly, can one automate the process of writing functionDataToFunction which is a pain. There is a simple pattern, but I can't see how to automate the process. Maybe one has to use template Haskell?

Let me know if I did not formulate my question in a clear way!

Thank you!

Dominik Schrempf
  • 827
  • 8
  • 14
  • The instances can be derived (and so can the template haskell splice). Why do you need the `Function` type? Where do you use it where 'frozen' `FunctionData` wouldn't suffice? – Iceland_jack Mar 27 '22 at 02:39
  • You are right, the frozen `FunctionData` would suffice. But somehow it doesn't feel right. Values of type `Function` are separate entities, and I only use `FunctionData` to be able to store and parse them. I could now go and encode all members of type `Function` as separate data types and collect them in `FunctionData`, but meh. It feels like matching the structure of the code to a side constraint, namely the necessity to store/read values of type `Function`. – Dominik Schrempf Mar 27 '22 at 19:47

0 Answers0