jamescard23
jamescard23

Reputation: 11

"Extending" an interface to allow for optional usage of function in instances

I am trying to add optional spacing into generated source code, the source code is generated into several languages like Python and Java.

I have an abstract file (non final code language specific) I have a function for creating the "if" control statement. It is similar to:

ifConditions :: (RendererSym r) => (Doc -> Doc) -> Doc -> Doc -> Doc -> [(SyValue r, MBody r)] -> MBody r -> MStatement r
ifConditions a startIf c d (x:xs) z = .....

That part is not too important here other than in the body of this function there is something like <+> startIf which I want to turn into <> optionalSpace startIf

No I could have instead simply changed <+> startIf to <> startIf and gone into each language specific file and changed the following

instance ControlStatements JavaGenCode where
  ifConditions = G.ifConditions a startIf b c

into the following if I wanted a space. prepSpace could be imported from an "abstract" file into each language specific rendering file as needed.

prepSpace :: Doc -> Doc 
prepSpace x = space <> x

instance ControlStatements JavaGenCode where
  ifConditions = K.ifConditions a (prepSpace startIf) b c

Instead is it possible (a good idea) to add this to the ControlStatements class?

class (BSym r, VSym r) => ControlStatements r where
  ifConditions :: [(SyValue r, MBody r)] -> MBody r -> MStatement r
  optionalSpace :: Label -> MStatement r

Then in each language specific rendering file:


instance ControlStatements JavaGenCode where
  ifConditions = K.ifConditions a startIf b c  --same as before
  optionalSpace = K.optSpace Empty
  

and in K file:

optionalSpace :: (RendererSym r) => Label -> MStatement r
optionalSpace n = ...

My main confusion is tying it all back into ifConditions. Now that

  1. I have optionalSpace in the ControlStatements class
  2. I have an instance in instance ControlStatements JavaGenCode, as needed
  3. optionalSpace is defined in K

How can I tie this back into the ifConditions function, so that I can use <> optionalSpace startIf? What am I overlooking here?

Upvotes: 1

Views: 65

Answers (1)

Li-yao Xia
Li-yao Xia

Reputation: 33439

There's a lot of missing context (why is optionalSpace :: Label -> MStatement r being used like it's Doc -> Doc (in <> optionalSpace startIf)? Why is ifConditions a method if you're always going to implement it using K.ifConditions? ...)

A shot in the dark.

Try defining a wrapper around K.ifConditions in the file containing the ControlStatements class,

class ControlStatements r where
  ifConditions :: ...
  optionalSpace :: ...

kifConditions :: ControlStatements r => ...
kifConditions a startIf b c = K.ifConditions a (optionalSpace startIf) b c

Upvotes: 3

Related Questions