Generate a name in the given case style taking into account the
reserved word of the language. Note that despite the fact that those
name are mainly to be used in code rendering (type Doc), we return a
String here to allow further manipulation of the name (like
disambiguation) which is not possible in the Doc type.
Examples:
>>> mkName [] LowerCase "FooBAR"
"foobar"
>>> mkName [] UpperCase "FooBAR"
"FOOBAR"
>>> mkName [] SnakeCase "FooBAR"
"foo_bar"
>>> mkName [] CamelCase "FooBAR"
"FooBAR"
>>> mkName [] CamelCase "Foo_bar"
"FooBar"
>>> mkName [] MixedCase "FooBAR"
"fooBAR"
>>> mkName ["foobar"] LowerCase "FooBAR"
"foobar_"
>>> mkName ["foobar", "foobar_"] LowerCase "FooBAR"
"foobar__"