@@ -117,21 +117,32 @@ restrictPositionForApplication f app = do
117
117
------------------------------------------------------------------------------
118
118
-- | Introduce a lambda binding every variable.
119
119
intros :: TacticsM ()
120
- intros = intros' Nothing
120
+ intros = intros' IntroduceAllUnnamed
121
+
122
+
123
+ data IntroParams
124
+ = IntroduceAllUnnamed
125
+ | IntroduceOnlyNamed [OccName ]
126
+ | IntroduceOnlyUnnamed Int
127
+ deriving stock (Eq , Ord , Show )
128
+
121
129
122
130
------------------------------------------------------------------------------
123
131
-- | Introduce a lambda binding every variable.
124
132
intros'
125
- :: Maybe [OccName ] -- ^ When 'Nothing', generate a new name for every
126
- -- variable. Otherwise, only bind the variables named.
133
+ :: IntroParams
127
134
-> TacticsM ()
128
- intros' names = rule $ \ jdg -> do
135
+ intros' params = rule $ \ jdg -> do
129
136
let g = jGoal jdg
130
137
case tacticsSplitFunTy $ unCType g of
131
138
(_, _, [] , _) -> cut -- failure $ GoalMismatch "intros" g
132
139
(_, _, args, res) -> do
133
140
ctx <- ask
134
- let occs = fromMaybe (mkManyGoodNames (hyNamesInScope $ jEntireHypothesis jdg) args) names
141
+ let gen_names = mkManyGoodNames (hyNamesInScope $ jEntireHypothesis jdg) args
142
+ occs = case params of
143
+ IntroduceAllUnnamed -> gen_names
144
+ IntroduceOnlyNamed names -> names
145
+ IntroduceOnlyUnnamed n -> take n gen_names
135
146
num_occs = length occs
136
147
top_hole = isTopHole ctx jdg
137
148
bindings = zip occs $ coerce args
@@ -148,6 +159,24 @@ intros' names = rule $ \jdg -> do
148
159
& # syn_val %~ noLoc . lambda (fmap bvar' bound_occs) . unLoc
149
160
150
161
162
+ ------------------------------------------------------------------------------
163
+ -- | Introduce a single lambda argument, and immediately destruct it.
164
+ introAndDestruct :: TacticsM ()
165
+ introAndDestruct = do
166
+ hy <- fmap unHypothesis $ hyDiff $ intros' $ IntroduceOnlyUnnamed 1
167
+ -- This case should never happen, but I'm validating instead of parsing.
168
+ -- Adding a log to be reminded if the invariant ever goes false.
169
+ --
170
+ -- But note that this isn't a game-ending bug. In the worst case, we'll
171
+ -- accidentally bind too many variables, and incorrectly unify between them.
172
+ -- Which means some GADT cases that should be eliminated won't be --- not the
173
+ -- end of the world.
174
+ unless (length hy == 1 ) $
175
+ traceMX " BUG: Introduced too many variables for introAndDestruct! Please report me if you see this! " hy
176
+
177
+ for_ hy destruct
178
+
179
+
151
180
------------------------------------------------------------------------------
152
181
-- | Case split, and leave holes in the matches.
153
182
destructAuto :: HyInfo CType -> TacticsM ()
0 commit comments