|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
Nice addition to Foreign: castAnyThis could be beside castPtr, castCharToCChar etc.
---- 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) ---- GHCi: > let a = -1000 :: Int16 > castAny a :: Word16 --> 64536 > castAny a :: Ptr () 0xb4c2fc18 > castAny (castAny a :: Ptr ()) :: Int16 -1000 > let b = pi :: CLDouble > b 3.141592653589793 > castAny b :: CInt 1413754136 > castAny b :: Ptr () 0x54442d18 > castAny b :: CFloat 3.3702806e12 > castAny b :: Int8 24 At minimum, this is safer than 'unsafeCoerce'. What do you think? Best, Maurício _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
|
Re: Nice addition to Foreign: castAnyOn Tue, Oct 27, 2009 at 12:48:32AM -0200, Maurício CA wrote:
> This could be beside castPtr, castCharToCChar etc. > > ---- > > 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) > > ---- > > GHCi: > > > let a = -1000 :: Int16 > > castAny a :: Word16 --> > 64536 > > castAny a :: Ptr () > 0xb4c2fc18 > > castAny (castAny a :: Ptr ()) :: Int16 > -1000 > > > let b = pi :: CLDouble > > b > 3.141592653589793 > > castAny b :: CInt > 1413754136 > > castAny b :: Ptr () > 0x54442d18 > > castAny b :: CFloat > 3.3702806e12 > > castAny b :: Int8 > 24 > > > At minimum, this is safer than 'unsafeCoerce'. What do you think? 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. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
|
Re: Nice addition to Foreign: castAny>> 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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@... http://www.haskell.org/mailman/listinfo/haskell-cafe |
| Free embeddable forum powered by Nabble | Forum Help |