MAINT: Refactor logic in maybe_convert_*
Creates a Seen class to abstract objects encountered when doing type conversions.

Follow-up to #15005.
you need to pass the structure to the functions themselves

but i think a class is better here actually @jreback : Good catch regarding classes.  Fixed. ## [Current coverage](https://codecov.io/gh/pandas-dev/pandas/pull/15018?src=pr) is 84.77% (diff: 100%)
> Merging [#15018](https://codecov.io/gh/pandas-dev/pandas/pull/15018?src=pr) into [master](https://codecov.io/gh/pandas-dev/pandas/branch/master?src=pr) will not change coverage

```diff
@@             master     #15018   diff @@
==========================================
  Files           145        145          
  Lines         51129      51129          
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
  Hits          43344      43344          
  Misses         7785       7785          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [9947a99...531a361](https://codecov.io/gh/pandas-dev/pandas/compare/9947a99d04b87e7441f062d6b5eca281ef15deb7...531a361d79e4b3ef0f08ce59a8976fdaf729c4c3?src=pr) @jreback : Addressed all comments, and everything is green still. @jreback : Made the requested changes, and everything is green. Small question (and sorry that you already changed all those once before), but can you name it `seen.int`, `seen.null`, etc instead of `see.sint`, `seen.snull`, .. ? 
IMO that reads easier (and sint and snull actually mean other things, or at least in Dutch :-)) @jorisvandenbossche : Fair enough (what do they mean, just curious?).  With underscores (as @jreback suggested) or none?  I'm inclined to go with no underscores since not declaring them public makes it pretty clear I think that they are private but want to double check. underscores are not needed here I think (if we add an underscore, I would make the class `_Seen` (the instantation can still be `seen`)

(sint -> saint, snul(l) -> nitwit/squib (don't know the exact translation)) @jorisvandenbossche : Very well.  Can rename without underscores. i don't think u can name a struct member the same as its type e.g.

int int

is not valid code (python or c) i see the renaming - that is ok

lgtm then @gfyoung my last 2 comments are meant, not really to simplify the code much, but more to make it a bit easier to read w/o having to think thru all of the possible cases. @jreback : Certainly.  There was another similar refactoring that I did for `is_bool` too. lgtm. just give a quick perf test (locally) and ping on green. @jreback : No major perf impact, and everything is green.  Ready to merge if there are no other concerns. thanks!