UArray for newtypes (LogFloat)

Hello, So, I would like to make an UArray of LogFloat. They are a newtype of Double, but the type system can't see trough newtypes. So I wonder if it is acceptable to exploit the fact that the internal representation of newtypes don't change to use some safe unsafeCoerces and create an instance of IArray for UArray of LogFloat. I've looked at the core of the code below and it seems sane, and -Wall only warn about the orphan instance, so I would also like to ask to include this instance in logfloat package itself (I've sent a copy of this message to LogFloat's maintainer). {-# LANGUAGE MultiParamTypeClasses #-} import Data.Array.Base import Data.Array.Unboxed (UArray) import Data.Number.LogFloat import Unsafe.Coerce -- For testing below import Data.Array.Unboxed as U import Test.QuickCheck {-# INLINE from #-} from :: UArray a LogFloat -> UArray a Double from = unsafeCoerce {-# INLINE to #-} to :: UArray a Double -> UArray a LogFloat to = unsafeCoerce {-# INLINE func #-} func :: (LogFloat -> a -> LogFloat) -> (Double -> a -> Double) func = unsafeCoerce instance IArray UArray LogFloat where {-# INLINE bounds #-} bounds = bounds . from {-# INLINE numElements #-} numElements = numElements . from {-# INLINE unsafeArray #-} unsafeArray lu = to . unsafeArray lu . unsafeCoerce {-# INLINE unsafeAt #-} unsafeAt = unsafeCoerce . unsafeAt . from {-# INLINE unsafeReplace #-} unsafeReplace arr = to . unsafeReplace (from arr) . unsafeCoerce {-# INLINE unsafeAccum #-} unsafeAccum f arr = to . unsafeAccum (func f) (from arr) {-# INLINE unsafeAccumArray #-} unsafeAccumArray f initialValue lu = to . unsafeAccumArray (func f) (unsafeCoerce initialValue) lu test1 :: [Double] -> Bool test1 elms' = elms == U.elems arr where arr :: UArray Int LogFloat arr = U.listArray (1, length elms) elms elms = map (logFloat . abs) elms' test2 :: [Double] -> Bool test2 elms' = product elms == arr U.! 1 where arr :: UArray Int LogFloat arr = U.accumArray (*) 1 (1, 1) [(1,x) | x <- elms] elms = map (logFloat . abs) elms' main :: IO () main = quickCheck test1 >> quickCheck test2 -- Felipe.

Hello Felipe, Saturday, March 7, 2009, 4:22:04 PM, you wrote:
So, I would like to make an UArray of LogFloat. They are a newtype of Double
this is possible in UArray reimplementation done in ArrayRef library http://haskell.org/haskellwiki/Library/ArrayRef although the library itself may be not compatible with ghc 6.10. try to search on hackage -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

bulat.ziganshin:
Hello Felipe,
Saturday, March 7, 2009, 4:22:04 PM, you wrote:
So, I would like to make an UArray of LogFloat. They are a newtype of Double
this is possible in UArray reimplementation done in ArrayRef library http://haskell.org/haskellwiki/Library/ArrayRef although the library itself may be not compatible with ghc 6.10. try to search on hackage
Can't you also just using generic newtype deriving? E.g. a UArr instance for free: {-# LANGUAGE GeneralizedNewtypeDeriving #-} import Data.Array.Vector newtype LogFloat = LogFloat Double deriving (Eq,Ord,Show,Num,UA) main = print . sumU $ replicateU 1000 (LogFloat pi) Which, btw, still triggers all the usual fusion: $wfold :: Double# -> Int# -> Double# $wfold = \ (ww_s14A :: Double#) (ww1_s14E :: Int#) -> case ww1_s14E of wild_B1 { __DEFAULT -> $wfold (+## ww_s14A 3.141592653589793) (+# wild_B1 1); 1000 -> ww_s14A $ time ./A LogFloat 3141.5926535897806 ./A 0.00s user 0.00s system 154% cpu 0.004 total -- Don
participants (3)
-
Bulat Ziganshin
-
Don Stewart
-
Felipe Lessa