4

I have lens based code that expects a certain data structure:

makeLenses ''Pool
...
pool ^. objects ^? _head :: Maybe Object

This code assumes that:

objects ::
  Functor f =>
  ([Object] -> f [Object]) -> Pool -> f Pool

But I want to introduce new information to the structure and new lens will become:

objects ::
  Functor f =>
  ([DebugInfo Object] -> f [DebugInfo Object]) -> Pool -> f Pool

My goal is to avoid any changes existing code as if it were complex project under maintenance.

Since I use lens library, I suppose it should be possible to provide a new module providing a "backported" objects lens so that I do not need to change old code (except imports maybe).

Is this plausible approach? Is there is a limitation lurking somewhere? Type classes or module system come to mind. I also suspect that I may have a problem with old code being unable to "reconstruct" a new structure. Do I need row type polymorphism to do that?

Lastly, if this can be done, how should I structure my modules to keep proper separation?

sevo
  • 4,559
  • 1
  • 15
  • 31

1 Answers1

1

I'm not sure why you need to modify the objects function instead of creating a new one. However, for your last question : old code reconstructing the new structure , the standard way is to have a default value and build any new values using this value and modifying it , like

data Foo = Foo { foo :: String, bar :: Int }
fooDef = Foo "" 0

newFoo :: String -> Int -> Foo
newFoo f b= fooDef { foo = f, bar = b }

This way, when you add a new field to Foo you only need to upade fooDef. However, it's probably better to not use it and update manually the code whereever it break. That's why you are using static typing after all, aren't you ?

mb14
  • 22,276
  • 7
  • 60
  • 102