selectEntries :: forall err a.
                 (err -> String)
              -> (Tar.Entry -> Maybe a)
              -> Tar.Entries err
              -> UploadMonad [a]
selectEntries formatErr select = extract []
  where
    extract :: [a] -> Tar.Entries err -> UploadMonad [a]
    extract _        (Tar.Fail err)           = throwError (formatErr err)
    extract selected  Tar.Done                = return selected
    extract selected (Tar.Next entry entries) =
      case select entry of
        Nothing    -> extract          selected  entries
        Just saved -> extract (saved : selected) entries
selectEntries :: forall err a.
                 (err -> String)
              -> (Tar.Entry -> Maybe a)
              -> Tar.Entries err
              -> UploadMonad [a]
selectEntries formatErr select = extract []
  where
    extract :: [a] -> Tar.Entries err -> UploadMonad [a]
    extract _        (Tar.Fail err)           = throwError (formatErr err)
    extract selected  Tar.Done                = return selected
    extract selected (Tar.Next entry entries) =
      case select entry of
        Nothing    -> extract          selected  entries
        Just saved -> extract (saved : selected) entries
selectEntries formatErr select = extract []
  where
    extract :: [a] -> Tar.Entries err -> UploadMonad [a]
    extract _        (Tar.Fail err)           = throwError (formatErr err)
    extract selected  Tar.Done                = return selected
    extract selected (Tar.Next entry entries) =
      case select entry of
        Nothing    -> extract          selected  entries
        Just saved -> extract (saved : selected) entries