NoBugs
NoBugs

Reputation: 9512

Creating an array in Haskell

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

Answers (2)

ehird
ehird

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

Daniel Fischer
Daniel Fischer

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

Related Questions