I'm trying to create a type called SmartArray. It is a type synonym for an array. If the element type can be unboxed, then SmartArray is an unboxed array. Otherwise, it is a boxed array.<br><br>For instance, <br><br>
(SmartArray Int Double) is the same as (UArray Int Double)<br>(SmartArray Int String) is the same as (Array Int String)<br><br>However, my implementation of SmartArray requires me to create an instance of a selector class to tell the compiler wheither the type is boxed or unboxed. I'm hoping to avoid creating instances of the selector class for every possible type. I'd be grateful for any suggestions.<br>
<br>Please see my code:<br><br><span style="font-family: courier new,monospace;">{-# OPTIONS_GHC </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> -fglasgow-exts </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> -fbreak-on-exception </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> -XOverlappingInstances</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#-}</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">import Data.Ix</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">import Data.Array.Unboxed</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">import Data.Complex</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">type SmartArray i e = (Ix i, SmartArraySelector a e) => (a i e)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace; color: rgb(51, 0, 153);">-- smartArray is similar to array function from Data.Array. But, it</span><br style="font-family: courier new,monospace; color: rgb(51, 0, 153);"><span style="font-family: courier new,monospace; color: rgb(51, 0, 153);">-- will return a UArray if e can be unboxed. Otherwise, it returns an Array.</span><br style="font-family: courier new,monospace; color: rgb(51, 0, 153);">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">smartArray :: (i, i) -> [(i, e)] -> SmartArray i e</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">smartArray bnd eLst = array bnd eLst </span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">class (IArray a e) => SmartArraySelector a e | e -> a where</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> arrayType :: Ix i => a i e -> a i e</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> arrayType = id</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- SmartArraySelector selects UArray for all types that can be</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- unboxed. An instance has to be created for each unboxed type. I'd</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- like to avoid listing all unboxed types here. However, since there</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- are only a few unboxed types, it's not too burdensome to list them</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- all. (For brevity, I didn't create all possible instances.)</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">instance SmartArraySelector UArray Bool where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">instance SmartArraySelector UArray Char where</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">instance SmartArraySelector UArray Double where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">instance SmartArraySelector UArray Float where</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">instance SmartArraySelector UArray Int where</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- SmartArraySelector selects Array for all types that can't be</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);"><span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- unboxed. An instance has to be created for EVERY possible unboxed</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- type that might be used with SmartArray. Since, the list of</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);"><span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- possible types is unlimited, this is pretty annoying.</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<br style="font-family: courier new,monospace; color: rgb(0, 0, 102);"><span style="font-family: courier new,monospace;">instance SmartArraySelector Array String where</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">instance SmartArraySelector Array (Complex e) where</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- I'd like to replace all the boxed instances above with one instance</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- like . . .</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);"><span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">--</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- instance SmartArraySelector Array e where</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);"><span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">--</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- However, this generates an error even though,</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);"><span style="font-family: courier new,monospace; color: rgb(0, 0, 102);">-- -XOverlappingInstances turned on.</span><br style="font-family: courier new,monospace; color: rgb(0, 0, 102);">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">test e = smartArray (0,10) [ (i,e) | i <- [0..10]]</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br>