[Haskell-cafe] Ix, Random, and overlapping instances
Bulat Ziganshin
bulat.ziganshin at gmail.com
Mon Aug 21 04:03:42 EDT 2006
Hello Lambda,
Monday, August 21, 2006, 1:20:26 AM, you wrote:
> Greetings Haskellers,
> I have recently found myself in a situation where I was needing to
> general tuples of randomized things; in my case, two coordinates and
> a custom data type, Direction. As it is always better to generalize,
> I decided to try to write some code which would generalize randomR to
> any type which is Ix-able:
>> instance Ix i => Random i where
>> random = error "No supported instance for random"
>> randomR r g
>> = let
>> r' = range r
>> (i, g') = randomR (0,length r'-1) g
>> in
>> (r' !! i, g')
using of (!!) is very inefficient. i don't think that GHC will
optimize such code to just arithmetic operations
> This works splendidly; with my given example above, I could do:
>> data Dir = N | NE | E | SE | S | SW | W | NW deriving (Eq, Ord,
> Show, Ix)
> ghci> newStdGen >>= print . take 10 . randomRs ((1,1,N),(10,10,NW))
> [(5,4,S), (3,10,SE), (6,5,N), (6,6,NW), (10,8,SE), (3,10,W),
> (10,3,E), (1,6,NE), (10,10,SE), (3,3,S)]
> As you can see, this results in random tuple(s) of these indexable
> types. My implementation required -fallow-overlapping-instances and -
> fallow-undecidable-instances for the code to compile.
> A few questions:
> 1) How does the compiler determine how to choose a particular
> instance for those cases where they overlap?
it selects most specific instance, preferring concrete types over type
classes. but it don't take into account hierarchy of classes. afair,
chapter 7 of GHC user's guide considers type system extensions
> I noticed that if I
> tried to generate a random :: Int, I was getting the error message
> defined in the above instance, indicating that the compiler was
> choosing my implementation over the default for Int (obviously
> because Int is an instance of Ix). Is there some way to exclude
> classes in the class qualifier, or to provide an instance as a
> default case without resorting to -fallow-overlapping-instances?
it's better to show your complete code. as one possible workaround i
can suggest the following:
class Ix i => Random i ....
instance Random Int ...
instance Random (Int,Int) -- default definitions will be used
> 2) Is there a logical overlap between class Ix and class Bounded? It
> seems that we could use the ranges of data types of Bounded to
> generate a reasonably sane `random` implementation for all Ix, if we
> can guarantee that all Ix instances are Bounded. Would adding an
> additional class constraint be sufficient to catch the major cases?
> i.e., instance (HasBounds i, Ix i) => Random i where ...
btw, how about the following:
instance (Enum i, Bounded i) => Random i where ...
and then defining instances for tuples? it will be efficient and
overlappings-free
> 3) Is there some reason that Ix is restricted to the Int datatype?
> Is there anything preventing us from moving to a genericIx,or
> something along those lines which support any integral type (say
> Integer), or is it merely for performance reasons that we use Int?
> Is the expectation that if you are using spaces larger than what an
> Int can accommodate, you should be using a different mechanism?
i think that this just because Ix was introduced solely for array
indexing which 1) should be fast, 2) almost don't require indexes
larger than Int can hold
--
Best regards,
Bulat mailto:Bulat.Ziganshin at gmail.com
More information about the Haskell-Cafe
mailing list