Reputation: 9512
I can construct an array with:
array ((0,0),(10,10)) [((x,y),(x)) | x<-[0..10], y<-[0..10]]
but I can't construct it with a function, not even something as simple as:
array ((0,0),(10,10)) [((x,y),f(x)) | x<-[0..10], y<-[0..10]]
What's wrong with this?? Specifically, how can I convert the "x" to a Realfrac?
Edit - Nevermind, I was using function fromIntegral(num) num
instead of function (fromIntegral num) num
.
Upvotes: 2
Views: 4078
Reputation: 40797
The problem is that when you say (x*1.5)
, you're forcing x
to be a Fractional number — such as Float, Double or Rational — since (*)
takes two values of the same type and returns a value of that same type, and of course 1.5 is a fractional number.
The problem arises because you can't make an array indexed by a floating-point number, only things like integers, tuples of integers and so on.1 What you probably mean to do is to keep x
and y
as integers, but convert them to a fractional type to calculate the value:
array ((0,0),(10,10)) [((x,y), fromIntegral x * 1.5) | x<-[0..10], y<-[0..10]]
Here, x
and y
are Integers, but fromIntegral x
is a Double.2 What fromIntegral
does is convert any Integral type (like Int, Int64, or Integer) into any Num (in this case, Double):
fromIntegral :: (Integral a, Num b) => a -> b
The end result is an array indexed by (Integer, Integer)
, with values of type Double, which is presumably what you wanted in the first place. :)
1 Specifically, any instance of the Ix type-class will do; you can see the full list in the documentation.
2 As for why Integer and Double are picked rather than any other Integral or Fractional, this is due to Haskell's defaulting mechanism. Basically, if you have an ambiguous numeric type in your program, it's first tried with Integer and if that doesn't work (e.g. because the type has to be Fractional, which, as we've established, Integer isn't), Double is tried instead. This is fairly arbitrary, but helps to eliminate ambiguity where it would otherwise crop up in a lot of silly places.
Upvotes: 3
Reputation: 183978
The indices types must belong to the Ix
class. There is no instance for types like Double
or Float
, for understandable reasons. But you try to multiply with a Fractional
number. You must transform the index to appropriate type, ((x,y), fromIntegral x * 1.5)
should work.
Upvotes: 3