[Haskell-cafe] Re: Nice addition to Foreign: castAny

Maurí­cio CA mauricio.antunes at gmail.com
Sat Nov 7 23:47:32 EST 2009


>> castAny :: (Storable a, Storable b) => a -> b
>> castAny = unsafePerformIO . genericCast
>>   where
>>     genericCast :: (Storable a, Storable b) => a -> IO b
>>     genericCast v = return undefined >>= \r ->
>>       allocaBytes (max (sizeOf v) (sizeOf r)) $ \p ->
>>         poke p v >> if False then return r else peek (castPtr p)

>>    > let a = -1000 :: Int16
>>    > castAny a :: Word16  -->
>>    64536
>>    > castAny a :: Ptr ()
>>    0xb4c2fc18

> Try it on a big endian architecture, or one that has alignment
> restrictions, or a different size for HsChar or so forth. Casting by
> 'punning' (as the C folks like to call it) does have uses, but they are
> generally hardware dependent and useful only in certain rare
> circumstances that a generic cast probably isn't likely to fill.

Do you think this could be used as a way to handle
C unions? If I had something like

union example {
   struct firstview {
     char c;
     int n;
   } fv;
   long double ld;
};

and 'firstview' had been mapped in Haskell as, say,

   FirstView {firstViewC :: CChar, firstVewN :: CInt}

I could check what I would get after pokeing values
using:

(firstViewN . unionCast) (pi :: CDouble)

Note that I changed the name from castAny to unionCast
to reflect its use.

Thanks for your comments,
Maurício



More information about the Haskell-Cafe mailing list