@@ -74,6 +74,7 @@ data Test
74 = IsCtor N.Name Index.ZeroBased Int Can.CtorOpts
74 = IsCtor N.Name Index.ZeroBased Int Can.CtorOpts
77 | IsInt Int
78 | IsInt Int
78 | IsChr Text
79 | IsChr Text
79 | IsStr Text
80 | IsStr Text
@@ -145,8 +146,17 @@ isComplete tests =
146 length tests == 2
147 length tests == 2
@@ -158,58 +168,63 @@ the only variant so we can skip doing any tests on it.
159flattenPatterns :: Branch -> Branch
169flattenPatterns :: Branch -> Branch
160flattenPatterns (Branch goal pathPatterns) =
170flattenPatterns (Branch goal pathPatterns) =
161− Branch goal (concatMap flatten pathPatterns)
171+ Branch goal (foldr flatten [] pathPatterns)
164−flatten :: (Path, Can.Pattern) -> [(Path, Can.Pattern)]
174+flatten :: (Path, Can.Pattern) -> [(Path, Can.Pattern)] -> [(Path, Can.Pattern)]
165−flatten pathPattern@(path, A.At region pattern) =
175+flatten pathPattern@(path, A.At region pattern) otherPathPatterns =
166 case pattern of
176 case pattern of
167 Can.PVar _ ->
177 Can.PVar _ ->
168− [pathPattern]
178+ pathPattern : otherPathPatterns
170 Can.PAnything ->
180 Can.PAnything ->
171− [pathPattern]
181+ pathPattern : otherPathPatterns
173− Can.PTuple a b Nothing ->
183+ Can.PCtor _ _ (Can.Union _ _ numAlts _) _ _ ctorArgs ->
174− concatMap flatten (subPositions path [a,b])
184+ if numAlts == 1 then
185+ case map dearg ctorArgs of
187+ flatten (Unbox path, arg) otherPathPatterns
176− Can.PTuple a b (Just c) ->
189+ args ->
177− concatMap flatten (subPositions path [a,b,c])
190+ foldr flatten otherPathPatterns (subPositions path args)
192+ pathPattern : otherPathPatterns
179− Can.PCtor _ _ (Can.Union _ _ 1 _) _ _ ctorArgs ->
194+ Can.PTuple a b maybeC ->
180− case map dearg ctorArgs of
195+ flatten (Index Index.first path, a) $
181− [arg] ->
196+ flatten (Index Index.second path, b) $
182− flatten (Unbox path, arg)
197+ case maybeC of
184− args ->
201+ Just c ->
185− concatMap flatten (subPositions path args)
202+ flatten (Index Index.third path, c) otherPathPatterns
187− Can.PCtor _ _ _ _ _ _ ->
204+ Can.PUnit ->
188− [pathPattern]
205+ otherPathPatterns
190 Can.PAlias realPattern alias ->
207 Can.PAlias realPattern alias ->
208+ flatten (path, realPattern) $
191− (path, A.At region (Can.PVar alias)) : flatten (path, realPattern)
209+ (path, A.At region (Can.PVar alias)) : otherPathPatterns
193 Can.PRecord _ ->
211 Can.PRecord _ ->
194− [pathPattern]
212+ pathPattern : otherPathPatterns
199 Can.PList _ ->
214 Can.PList _ ->
200− [pathPattern]
215+ pathPattern : otherPathPatterns
202 Can.PCons _ _ ->
217 Can.PCons _ _ ->
203− [pathPattern]
218+ pathPattern : otherPathPatterns
205 Can.PChr _ ->
220 Can.PChr _ ->
206− [pathPattern]
221+ pathPattern : otherPathPatterns
208 Can.PStr _ ->
223 Can.PStr _ ->
209− [pathPattern]
224+ pathPattern : otherPathPatterns
211 Can.PInt _ ->
226 Can.PInt _ ->
212− [pathPattern]
227+ pathPattern : otherPathPatterns
215subPositions :: Path -> [Can.Pattern] -> [(Path, Can.Pattern)]
230subPositions :: Path -> [Can.Pattern] -> [(Path, Can.Pattern)]
@@ -281,55 +296,52 @@ testsAtPath selectedPath branches =
281 , Set.insert test visitedTests
296 , Set.insert test visitedTests
284− fst (foldr skipVisited ([], Set.empty) allTests)
299+ fst (foldr skipVisited ([], Set.empty) allTests)
287testAtPath :: Path -> Branch -> Maybe Test
302testAtPath :: Path -> Branch -> Maybe Test
288testAtPath selectedPath (Branch _ pathPatterns) =
303testAtPath selectedPath (Branch _ pathPatterns) =
289 case List.lookup selectedPath pathPatterns of
304 case List.lookup selectedPath pathPatterns of
290 Nothing ->
305 Nothing ->
293 Just (A.At _ pattern) ->
308 Just (A.At _ pattern) ->
294− case pattern of
309+ case pattern of
295− Can.PCtor _ _ (Can.Union _ _ numAlts opts) name index _ ->
310+ Can.PCtor _ _ (Can.Union _ _ numAlts opts) name index _ ->
296− Just (IsCtor name index numAlts opts)
311+ Just (IsCtor name index numAlts opts)
301− Can.PStr str ->
313+ Can.PList ps ->
302− Just (IsStr str)
314+ Just (case ps of { [] -> IsNil ; _ -> IsCons })
304− Can.PChr chr ->
316+ Can.PCons _ _ ->
305− Just (IsChr chr)
317+ Just IsCons
307− Can.PList [] ->
319+ Can.PTuple _ _ _ ->
308− Just IsNil
320+ Just IsTuple
310− Can.PList _ ->
322+ Can.PUnit ->
311− Just IsCons
323+ Just IsTuple
313− Can.PCons _ _ ->
325+ Can.PVar _ ->
314− Just IsCons
326+ Nothing
316− Can.PVar _ ->
328+ Can.PAnything ->
319− Can.PAlias _ _ ->
331+ Can.PInt int ->
320− error "aliases should never reach 'testAtPath' function"
332+ Just (IsInt int)
322− Can.PAnything ->
334+ Can.PStr str ->
323− Nothing
335+ Just (IsStr str)
325− Can.PUnit ->
337+ Can.PChr chr ->
326− Nothing
338+ Just (IsChr chr)
328− Can.PTuple _ _ _ ->
340+ Can.PRecord _ ->
331− Can.PRecord _ ->
343+ Can.PAlias _ _ ->
332− Nothing
344+ error "aliases should never reach 'testAtPath' function"
@@ -346,7 +358,7 @@ edgesFor path branches test =
346toRelevantBranch :: Test -> Path -> Branch -> Maybe Branch
358toRelevantBranch :: Test -> Path -> Branch -> Maybe Branch
347toRelevantBranch test path branch@(Branch goal pathPatterns) =
359toRelevantBranch test path branch@(Branch goal pathPatterns) =
348 case extract path pathPatterns of
360 case extract path pathPatterns of
349− Just (start, A.At region pattern, end) ->
361+ Found start (A.At region pattern) end ->
350 case pattern of
362 case pattern of
351 Can.PCtor _ _ (Can.Union _ _ numAlts _) name _ ctorArgs ->
363 Can.PCtor _ _ (Can.Union _ _ numAlts _) name _ ctorArgs ->
352 case test of
364 case test of
@@ -410,33 +422,50 @@ toRelevantBranch test path branch@(Branch goal pathPatterns) =
413− _ ->
425+ Can.PUnit ->
426+ Just (Branch goal (start ++ end))
428+ Can.PTuple a b maybeC ->
429+ Just (Branch goal (start ++ subPositions path (a : b : Maybe.maybeToList maybeC) ++ end))
414 Just branch
435 Just branch
416− _ ->
437+ Can.PRecord _ ->
417 Just branch
444 Just branch
420−extract
447+data Extract
421− :: Path
448+ = NotFound
422− -> [(Path, Can.Pattern)]
449+ | Found [(Path, Can.Pattern)] Can.Pattern [(Path, Can.Pattern)]
423− -> Maybe ([(Path, Can.Pattern)], Can.Pattern, [(Path, Can.Pattern)])
450+
452+extract :: Path -> [(Path, Can.Pattern)] -> Extract
424extract selectedPath pathPatterns =
453extract selectedPath pathPatterns =
425 case pathPatterns of
454 case pathPatterns of
427− Nothing
456+ NotFound
429 first@(path, pattern) : rest ->
458 first@(path, pattern) : rest ->
430 if path == selectedPath then
459 if path == selectedPath then
431− Just ([], pattern, rest)
460+ Found [] pattern rest
434 case extract selectedPath rest of
463 case extract selectedPath rest of
435− Nothing ->
464+ NotFound ->
436− Nothing
465+ NotFound
438− Just (start, foundPattern, end) ->
467+ Found start foundPattern end ->
439− Just (first : start, foundPattern, end)
468+ Found (first : start) foundPattern end
@@ -456,41 +485,20 @@ isIrrelevantTo selectedPath (Branch _ pathPatterns) =
456needsTests :: Can.Pattern -> Bool
485needsTests :: Can.Pattern -> Bool
457needsTests (A.At _ pattern) =
486needsTests (A.At _ pattern) =
458 case pattern of
487 case pattern of
459− Can.PVar _ ->
488+ Can.PVar _ -> False
462− Can.PAnything ->
489+ Can.PAnything -> False
463− False
490+ Can.PRecord _ -> False
464−
491+ Can.PCtor _ _ _ _ _ _ -> True
493+ Can.PCons _ _ -> True
495+ Can.PTuple _ _ _ -> True
465 Can.PAlias _ _ ->
499 Can.PAlias _ _ ->
466 error "aliases should never reach 'isIrrelevantTo' function"
500 error "aliases should never reach 'isIrrelevantTo' function"
471− Can.PCtor _ _ _ _ _ _ ->
@@ -573,9 +581,10 @@ instance Binary Test where
573 IsCtor a b c d -> putWord8 0 >> put a >> put b >> put c >> put d
581 IsCtor a b c d -> putWord8 0 >> put a >> put b >> put c >> put d
574 IsCons -> putWord8 1
582 IsCons -> putWord8 1
575 IsNil -> putWord8 2
583 IsNil -> putWord8 2
584+ IsTuple -> putWord8 3
576− IsChr a -> putWord8 3 >> put a
585+ IsChr a -> putWord8 4 >> put a
577− IsStr a -> putWord8 4 >> put a
586+ IsStr a -> putWord8 5 >> put a
578− IsInt a -> putWord8 5 >> put a
587+ IsInt a -> putWord8 6 >> put a
581 do word <- getWord8
590 do word <- getWord8
@@ -583,9 +592,10 @@ instance Binary Test where
583 0 -> liftM4 IsCtor get get get get
592 0 -> liftM4 IsCtor get get get get
584 1 -> pure IsCons
593 1 -> pure IsCons
585 2 -> pure IsNil
594 2 -> pure IsNil
586− 3 -> liftM IsChr get
596+ 4 -> liftM IsChr get
587− 4 -> liftM IsStr get
597+ 5 -> liftM IsStr get
588− 5 -> liftM IsInt get
598+ 6 -> liftM IsInt get
589 _ -> error "problem getting DecisionTree.Test binary"
599 _ -> error "problem getting DecisionTree.Test binary"