I think you have a (rather common among beginners - I had it myself) misunderstanding of what type classes are. The way Haskell works is logically incompatible with "check[ing] a single value against all possible types of the Read typeclass". Instance selection is based on types. Only types.
You should not think of read
as a magical function that can return many types. It's actually a huge family of functions, and the type is used to select which member of the family to use. It's that direction of dependence that matters. Classes create a case where values (usually functions, but not always) - the things that exist at run time - are chosen based on types - the things that exist at compile time.
You're asking "Why not the other direction? Why can't the type depend on the value?", and the answer to that is that Haskell just doesn't work that way. It wasn't designed to, and the theory it was based on doesn't allow it. There is a theory for that (dependent types), and there are extensions being added to GHC that support an increasing set of feature that do some aspect of dependent typing, but it's not there yet.
And even if it was, this example would still not work the way you want. Dependent types still need to know what type something is. You couldn't write a magical "returns anything" version of read
. Instead, the type for read
would have to involve some function that calculates the type from the value, and inherently only works for the closed set of types that function can return.
Those last two paragraphs are kind of an aside, though. The important part is that classes are ways to go from types to values, with handy compiler support to automatically figure it out for you most of the time. That's all they were designed to do, and it's all that they can do. There are advantages to this design, in terms of ease of compilation, predictability of behavior (open world assumption), and ability to optimize at compile time.
read "5"
should have? It's not so simple to say – sararead "5"
, because you'd just write5
. What concrete type shouldread someUnknownString
have? – Benshow
is polymorphic in its argument type - which is something quite normal. Butread
is polymorphic in its result type, which means without either being told explicitly by a type signature, or inference from the other functions you use the result with, the compiler can't figure out what you want. – Robin Zigmondread "4" 3
will give you a missing instance error (in the absence of certain very unorthodox additional code). Can you give an example of what you mean, since you don't seem to be using standard terminology here? – Daniel Wagner