- isFunLhs' loc (HsVar f) es
- | not (isRdrDataCon f) = Just (L loc f, False, es)
- isFunLhs' loc (HsApp f e) es = isFunLhs f (e:es)
- isFunLhs' loc (HsPar e) es@(_:_) = isFunLhs e es
- isFunLhs' loc (OpApp l (L loc' (HsVar op)) fix r) es
- | not (isRdrDataCon op) = Just (L loc' op, True, (l:r:es))
- | otherwise =
- case isFunLhs l es of
- Just (op', True, j : k : es') ->
- Just (op', True,
- j : L loc (OpApp k (L loc' (HsVar op)) fix r) : es')
- _ -> Nothing
- isFunLhs' _ _ _ = Nothing
+ go (L loc (HsVar f)) es
+ | not (isRdrDataCon f) = return (Just (L loc f, False, es))
+ go (L _ (HsApp f e)) es = go f (e:es)
+ go (L _ (HsPar e)) es@(_:_) = go e es
+ go e@(L loc (OpApp l (L loc' (HsVar op)) fix r)) es
+ | Just (e',es') <- splitBang e
+ = do { bang_on <- extension bangPatEnabled
+ ; if bang_on then go e' (es' ++ es)
+ else return (Just (L loc' op, True, (l:r:es))) }
+ -- No bangs; behave just like the next case
+ | not (isRdrDataCon op)
+ = return (Just (L loc' op, True, (l:r:es)))
+ | otherwise
+ = do { mb_l <- go l es
+ ; case mb_l of
+ Just (op', True, j : k : es')
+ -> return (Just (op', True, j : op_app : es'))
+ where
+ op_app = L loc (OpApp k (L loc' (HsVar op)) fix r)
+ _ -> return Nothing }
+ go _ _ = return Nothing