
The usual suggestion I see for this sort of thing is to create a typeclass for the operations you care about[1][2]. For example: ------------------------------------------------------------------------------------------- class HasOpen a where open :: a -> Handle data DB data FS openDB :: DB -> Handle openFS :: FS -> Handle instance DB HasOpen where open = openDB instance FS HasOpen where open = openFS ------------------------------------------------------------------------------------------- Of course, this doesn't allow you to have functions share the same name if they have different signatures, as in your (open :: FS -> File) example. To be honest, I think the C / Haskell approach of unambiguously-identified functions is clearly superior to the C++ / C# / Java "class as namespace" idiom, which has caused me no end of grief. Dynamic languages such as Python and Ruby, of course, can return anything from anywhere. This is nice in some cases, but having used both extensively I think (static typing+inference) is a better solution than dynamic typing.
Now, in Haskell we have type inference, which is "The Good Thing" as it allows to "validate" your program at compile time. Hence, the idea coming up to my mind is that type inference actually forbids a type-directed resolution of names as in C++ or Java.
Is this correct?
Type inference and static typing are separate; inference makes static typing usable, but static typing makes compile-type correctness verification easier. And it's not inference making your goal impossible, but the fact that Haskell (like C) does not support arbitrary overloading. [1] http://www.mail-archive.com/haskell-cafe@haskell.org/msg64844.html [2] http://stackoverflow.com/questions/1897306/haskell-record-syntax-and-type-cl...