
Bertram Felgenhauer wrote:
Jacques Carette wrote:
Bulat Ziganshin wrote:
malloc :: Storable a => IO (Ptr a) malloc = doMalloc undefined where doMalloc :: Storable b => b -> IO (Ptr b) doMalloc dummy = mallocBytes (sizeOf dummy)
Is there any reason to not code this as
malloc :: Storable a => IO (Ptr a) malloc = mallocBytes $ sizeof undefined
What type would the 'undefined' have in this context?
sizeOf has type Storable a => a -> Int -- that doesn't help.
The purpose of doMalloc is to force the type checker to choose the right type for that 'undefined'.
I still don't quite see it! To my eyes, the type of doMalloc and the type of malloc look exactly "the same", with neither providing more specificity than the other. Also, the 'undefined' can be of any type, as long as it is from class Storable. So it is a placeholder for a dictionary - what else does it need? [Constraint-typing-wise, it doesn't need anything else, but perhaps the issue is that I don't understand Haskell's type system quite well enough]. I guess I am also asking "Is there a GOOD reason why the simpler code can't be used?". Or maybe what I really need is malloc :: Storable a => IO (Ptr a) malloc = mallocBytes $ sizeof undefined::a ? That would make sense to me, since in a more general function I might have 2 instances (Storable a, Storable b) available, and 2 undefineds, and I could not know how to match them up deterministically in all cases. I guess I prefer a type annotation over a dummy function that is there just to force the type checker to believe me. If one has to force the type checker, may as well do it with a type, not code! Jacques