This is going to be a short post, maybe even a tweet size post. I’m going to highlight how to generate lenses for third party libraries because when I was searching for this information it wasn’t that easy to find.
My concern was less on the mechanics on how to generate them but more on best practices, I wasn’t sure if generating lenses for data types I don’t own is good practice. When I asked in fp-chat, I was told to “Go hog wild!” and didn’t get any opposing views. So that gave me the peace of mind to do this.
I’m going to use the purescript language library as an example since it’s the most recent library I had to work with.
I’m going to use
Control.Lens.TH. The default configuration of
makeLenses is it will only generate lenses for record fields that are prefixed with an underscore.
Before I can start generating lenses for the types I don’t own, I have to change the
makeLenses configuration a little bit.
module Util where import Language.Haskell.TH import Control.Lens.Operators import Control.Lens.TH mkCustomLenses :: Name -> DecsQ mkCustomLenses = makeLensesWith $ lensRules & lensField .~ (\_ _ name -> [TopName ( mkName $ nameBase name ++ "L" )]) -- you can append whatever suits your code base here, I chose to append "L"
It has to be in a separate module from where you generate the lenses because the compiler will complain with this error
After that setup you can start generating lenses!
module Optics where -- util import Util -- purescript import Language.PureScript.CST.Types makePrisms ''Declaration makePrisms ''Guarded makePrisms ''Expr mkCustomLenses ''ValueBindingFields mkCustomLenses ''Name mkCustomLenses ''Ident mkCustomLenses ''Labeled mkCustomLenses ''Where mkCustomLenses ''Wrapped mkCustomLenses ''Separated mkCustomLenses ''Module
Now, if I want to manipulate
Separated I can do something like
When it comes to sum types you can just use
makePrisms to generate prisms.
Optics by Example - Chris Penner