                (save-excursion
                  (goto-char (point-min))
                  (forward-line (1- (plist-get suggestion :line)))
-                 (if (search-forward-regexp "\\([[:space:]]*::\\|instance\\)[[:space:]]* (?\\([[:alnum:][:space:],?\n]+\\))?[[:space:]?\n]*=>" (point-max) t)
-                     (let* ((start (match-beginning 2))
-                            (end (match-end 2))
-                            (constraints
-                             (mapcar #'string-trim
-                                     (split-string (match-string 2)
-                                                   "[[:space:]]*,[[:space:]]*")))
-                            (nonredundant
-                             (cl-loop for r in (plist-get suggestion :redundancies)
-                                      with nonredundant = constraints
-                                      do (setq nonredundant (delete r nonredundant))
-                                      finally return nonredundant)))
-                       (goto-char start)
-                       (delete-char (- end start))
-                       (insert (string-join nonredundant ", ")))
-                   (message "Couldn't parse constraints"))))))
-
+                 (search-forward-regexp "[[:alnum:][:space:]\n]*=>")
+                 (backward-sexp 2)
+                 (let ((start (1+ (point))))
+                   (forward-sexp)
+                   (let* ((end (1- (point)))
+                          (constraints (intero-parse-comma-list
+                                        (buffer-substring start end)))
+                          (nonredundant
+                             (loop for r in (plist-get suggestion :redundancies)
+                                   with nonredundant = constraints
+                                   do (setq nonredundant (delete r nonredundant))
+                                   finally return nonredundant)))
+                     (goto-char start)
+                     (delete-char (- end start))
+                     (insert (string-join nonredundant ", "))))))))
 
         ;; Add a type signature to a top-level binding.
         (cl-loop

          ;;                             Functor var,
          ;;                             Applicative var,
          ;;                             Monad var)
          (when (string-match "Redundant constraints?:[\n[:space:]]*\\(\\([[:alnum:][:space:]]+\\)\\|(\\([[:alnum:][:space:],\n]+\\))\\).*\n.*In the " text)
            (setq note t)
            (add-to-list
             'intero-suggestions
             (let ((rest (substring text (match-end 0)))
                   (redundant (or (match-string 2 text) (match-string 3 text))))
               (list :type 'redundant-constraint
                     :redundancies (mapcar #'string-trim
                                           (split-string redundant
                                                         "[:space:]*,[:space:]*"))
                     :signature (mapconcat #'identity (split-string rest) " ")
                     :line (flycheck-error-line msg)))))
          ;; Add a note if we found a suggestion to make
          (when note
            (setf (flycheck-error-message msg)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auto actions

(defun intero-parse-comma-list (text)
  "Parse a list of comma-separated expressions."
  (loop for tok in (split-string text "[[:space:]\n]*,[[:space:]\n]*")
        with acc = nil
        append (let* ((clist (string-to-list tok))
                      (num-open (-count (lambda (c) (or (eq c ?\() (eq c ?\[)))
                                        clist))
                      (num-close (-count (lambda (c) (or (eq c ?\)) (eq c ?\])))
                                         clist)))
                 (cond
                  ((> num-open num-close) (progn (add-to-list 'acc tok) nil))
                  ((> num-close num-open) (let ((tmp (reverse (cons tok acc))))
                                            (setq acc nil)
                                            (list (string-join tmp ", "))))
                  (t (list tok))))))

(defun intero-apply-suggestions ()
  "Prompt and apply the suggestions."
