-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#15] Add lenses for config-related types #17
base: master
Are you sure you want to change the base?
Conversation
Problem: It's quite unconvenient to access config-related records' fields by hand, especially when it comes to nested ones. Solution: Implement simple `makeLenses` function to derive lenses for an arbitrary product type and add common lenses operators & types.
0158eca
to
a093735
Compare
@Martoon-00 |
Hmhm, given that you already have field type available within I also don't see obvious troubles we could get, but would like to follow the practices here unless there is a major reason not to do so. |
l ?= b = modify (l ?~ b) | ||
|
||
(&~) :: s -> State s a -> s | ||
s &~ l = execState l s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I think actually we don't need operators and other helpers, especially if this is a functionality that we will have to cover with tests (we would really have to). We may need Lens
type, but only if it will be used to define our new lenses.
The point is not to provide a simple replacement for lens
library, but rather to be compatible with lens
without depending on it. So that the user who wants to use our new lenses to configure the options, could use them along with lens
package; and the user who does not want to use lens could go completely without them.
body = [| (\x -> $(record a fieldName [|x|])) | ||
`fmap` $(appE (varE f) (appE (varE fieldName) (varE a))) | ||
|] | ||
record rec fld val = val >>= \v -> recUpdE (varE rec) [return (fld, v)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very-very good 👍
defLine = clause pats (normalB body) [] | ||
pats = [varP f, varP a] | ||
body = [| (\x -> $(record a fieldName [|x|])) | ||
`fmap` $(appE (varE f) (appE (varE fieldName) (varE a))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestion: if you use appE
in infix form here too, that should be slightly more readable.
TyConI (DataD _ _ _ _ [RecC _ fs] _) -> fs | ||
TyConI (NewtypeD _ _ _ _ (RecC _ fs) _) -> fs | ||
TyConI (DataD _ _ _ _ [_] _) -> | ||
error $ "Can't derive lenses without record selectors: " ++ datatypeStr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better use fail
, error
is for internal errors and will be reported respectively.
This adds common
Lens
types & operators and implements simplemakeLenses
template-haskell function to derive lenses for config-related types.The tutorial's yet to be updated.
Description
Related issue(s)
Resolves #15
✅ Checklist for your Pull Request
Related changes (conditional)
Tests
silently reappearing again.
Documentation
Public contracts
of Public Contracts policy.
and
Stylistic guide (mandatory)