-
-
Notifications
You must be signed in to change notification settings - Fork 368
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
Case splitting and lambda introduction #391
Conversation
I think this needs |
It would be nice if it were configurable to generate For the example in OP: fmapEither = \fab -> \case
Left c -> Left _
Right a -> Right _ Of course this feature request shouldn't interfere with this being merged! |
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.
Super cool, thanks @isovector and @TOTBWF !!!!
I won't claim to understand all that is going on, but see my comments for minor nits on ghcide specifics.
Tests would be very welcome in future PRs to ensure that the plugin doesn't break accidentally.
@pepeiborra what sorts of tests would you be interested in? Things to show the tactics do what they say? Or tests more along the lines of the plugin integration at large? |
src/Ide/LocalBindings.hs
Outdated
-- **WARNING:** This doesn't yet work over TH splices or arrow syntax --- and | ||
-- possibly other obscure pieces of the AST. | ||
dataBindings :: Data a => S.Set Id -> a -> M.Map SrcSpan (S.Set Id) | ||
dataBindings in_scope = foldMapOf biplate $ cool collect |
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.
This information is computed in .hie
files. If you look at the refmap
in the result of the GetHieFile
rule, you will get a map Map Identifier [(Span, IdentifierDetails Type)]
. IdentifierDetails
contains a set of ContextInfo
, from which you recover the scope for that particular identifier using getScopeFromContext
.
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.
I'd love to get rid of this; but if I'm reading your comment correctly, that mapping is the wrong direction. We want to go from a span to every binding in scope inside of it.
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.
Yes, you need to invert the map into something like a IntervalMap
, which should be pretty straightforward to construct. What we have is essentially a Map Name [Scope]
, what we need is an IntervalMap SrcLoc Name
, right?
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.
Delightfully good idea. I'll implement it today. Thanks!
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.
I gave this a go, and got as far as getting back a TypeIndex
from hie. But I can't figure out how to reconstitute this into a proper GHC Type
, which is necessary for how we've set up refinery
. Holding off on moving forwards until someone can point me in the right direction on that one!
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.
See #396, that should make this work
See the tests for the Eval plugin - golden tests to show that all the plugin salient features work as expected. |
I'll tackle the tests and suggestions tomorrow :) |
@expipiplus1 happy to implement that immediately after. Please file a bug if one doesn't already exist! |
@isovector done, thanks! #394 |
@pepeiborra tests are added and passing. |
Needs rebasing |
Yeah, i moved part of |
HLint will deal with that, whenever that plugin is completed. |
Rebased and everything is a go. The stack files need some new additions, but I was hoping CI would tell me what changes need to happen. How can we get CI running on this PR? |
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.
Thanks, great work here! Look forward to using it.
[WIP] Add Skeleton for Tactic Plugin Local bindings [WIP] Add more to the code action provider more cases for bindings is it a hole? Beginning of tactics machinery tactics machinery split out tactics machinery; finish porting tactics Haddock for tactics machinery Use a map for hypothesis Better types on LocalBindings render the result of running a tactic Hypothesis from bindings Sort types mostSpecificSpan Render Actually add the tactic plugin :) [WIP] Do stuff slightly better span better sorting for specific spans Fix size [WIP] It does the thing!! Multiple tactic actions Parenthesize if necessary [WIP] Home on the 'Range' destruct and homo fix naming and parens Cleanup Plugin Tactic context dependent destruct and homo Generalized interface More composable Remove TacticVariety Haddock Describe spooky monoidal behavior Only look at actual holes Auto if possible debugging Maybe grafting works now Transformation works; tree doesnt Remove debugging Proper indentation and parenthesizing Less fancy parenthesizing Don't crash if we can't lookup things Holes must start with an underscore Haddock pass Module restructuring Fix the cabal file Intros, and disable some of the unpolished tactics Disable autoIfPossible Fix stack.yaml Respond to simple PR comments. Get a proper dflags WIP on a better bindings interface Simplify dflags lookup and expose titles Tactic tests Add a few more tests Cleanup imports Haddock the tests Rebase on ghcide HEAD (haskell#378) * Rebase on top of ghcide HEAD * use Development.IDE to trim imports * Fix Eval plugin to use GhcSessionDeps Use stale data in explicit imports lens (haskell#383) This prevents the lenses from disappearing while editing, which causes lots of unpleasant jumping Create hls-plugin-api and move plugins to exe Keep current version Add hls-plugin-api component to cradle Move exe modules to main library Format .cabal files with `cabal-fmt --ident 2` Restore ghcide ref Fix cradles Move tactic plugin Almost there! Get the tests running again Empty commit for CI Add refinery to stack more stack woes Duplicate NoExt and less dependency on ghc Cradle is necessary bump ghcide submodule (haskell#396) * Bump ghcide submodule * Update stack descriptors Co-authored-by: Pepe Iborra <[email protected]> Update ghcide Compute an interval map of what's in scope Fix 'binding'
@isovector please review the last two commits. |
Hi, could we keep the default stack.yaml with ghc-8.6.5?, please |
Um, how do I trigger case splitting on argument like
In neovim I don't have those nice light bulbs to see where code actions are available and I've tried
Where should I put my text cursor exactly to see case splitting or is it only for case of? |
@Anrock try |
@wz1000 thanks, that works, however it produces |
pull requests welcome! |
@TOTBWF and I had a mini hackathon last weekend and this is the results. It provides case splitting, homomorphic case splitting[^1], and lambda introduction. It does a reasonable job of coming up with good names, and implements a lot of general-purpose machinery for other plugins.
[^1] Case splitting to the same datacons --- useful for writing things like functor instances.
It looks like this:
Fixes #323 --- although that usecase could be improved with a separate action that flattens
foo = \x y z -> bar
intofoo x y z = bar
.We have plans to follow this up with more type-directed code generation; a great deal of it is already implemented, but not yet polished. Most of
Ide.Plugin.Tactic.Tactics
is towards that purpose.