[web-devel] Simple mime-type package

Michael Snoyman michael at snoyman.com
Fri Apr 23 07:44:05 EDT 2010

On Thu, Apr 22, 2010 at 9:42 AM, Jeremy Shaw <jeremy at n-heptane.com> wrote:

> Hello,
> I am not especially excited about it. The fact that some mime-types are
> hard coded, and others are not is an annoying 'inconsistency'.
> There is no way to extend the list of supported types in user apps. And
> typeByExt has a rather limited set up extensions, declaring everything else
> to be application/octet-stream.
> The use of a type for the mime-types implies that you want to be pattern
> matching on the constructors in your code ? Can you give a use case for that
> ?
> I wouldn't say that type implies pattern matching. I think the type makes
code much clearer. For example, in Haskell I have:

type ChooseRep = [ContentType] -> IO (ContentType, Content)

I find that to be *much* clearer than

type ChooseRep = [String] -> IO (String, Content)

You could argue that I should just be using a type instead of a datatype,
but that's an old debate between convenience and compiler type-safety. You
could also argue that this should just be

newtype ContentType = ContentType String

I find three advantages for the current method. First, in theory passing
around a TypeHtml constructor takes less memory than a ContentType
"text/html; charset=utf-8", but I could be missing something about
optimizations here. Second, it's just a lot more convenient to write in the
first place. The alternative to having TypeHtml etc constructors would be:

typeHtml :: ContentType
typeHtml = ContentType "text/html; charset=utf-8"

Plus adding each function to the export list is just more tedious. Finally,
I find the code *looks* better using a constructor than a function, eg

chooseRep [TypeHtml, TypeJson]


chooseRep [typeHtml, typeJson]

though that's just a matter of taste.

I'm also not too concerned about the inconsistency, though I see where
you're coming from. One of the advantages I'd see of opening this into a
standalone package is that in theory the whole community could keep adding
mimetypes until this is very comprehensive.

I find your argument to be more apropos to the typeByExt function, since
that *is* a case where users would want to both extend and override library
defaults. I see two options here:

* Change typeByExt to have return type "Maybe ContentType", and then users
won't need to worry about the TypeOctet appearing all over the place. They
can choose whatever default they want. If they want to extend or override,
they just need to write their own function to be called before typeByExt.
* Don't provide a function at all; instead, provide a Map (or trie) with a
number of built-in extension -> mimetype mappings. Users could then just do
a lookup, as well as make changes to that Map.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/web-devel/attachments/20100423/43fe6b35/attachment.html

More information about the web-devel mailing list