
For some reason, the map function returns a list that has one more element than my input list. My input list is a range defined by [0, 60..359] (should translate into [0,60,120,180,240,300]). The function I'm giving to map is defined this way: ----- degreesToRadians :: Double -> Double degreesToRadians degrees = degrees * (pi / 180) ----- This is how I'm calling map overall: -----
map degreesToRadians [0,60..359] [0.0,1.0471975511965976,2.0943951023931953,3.141592653589793,4.1887902047863905,5.235987755982989,6.283185307179586 ]
As you can hopefully see, there are seven elements instead of six. Getting the length confirms this: -----
length [0,60..359] 6 length $ map degreesToRadians [0,60..359] 7
I do not seem to get this behaviour with the length if I either substitute the degreesToRadians function or substitute the [0,60..359] range. P.S. Is there a built-in function to convert degrees to radians and vice-versa?

That's because [0,60,..359] is not the same as [0,60..359] :: [Double]. So what you're passing to degreesToRadians is [0.0,60.0,120.0,180.0,240.0,300.0,360.0] and not [0,60,120,180,240,300]. I don't know why the Double version adds another number, though. On Jun 17, 2009, at 4:35 PM, Aaron MacDonald wrote:
For some reason, the map function returns a list that has one more element than my input list.
My input list is a range defined by [0, 60..359] (should translate into [0,60,120,180,240,300]).
The function I'm giving to map is defined this way: ----- degreesToRadians :: Double -> Double degreesToRadians degrees = degrees * (pi / 180) -----
This is how I'm calling map overall: -----
map degreesToRadians [0,60..359] [0.0,1.0471975511965976,2.0943951023931953,3.141592653589793,4.1887902047863905,5.235987755982989,6.283185307179586 ]
As you can hopefully see, there are seven elements instead of six. Getting the length confirms this: -----
length [0,60..359] 6 length $ map degreesToRadians [0,60..359] 7
I do not seem to get this behaviour with the length if I either substitute the degreesToRadians function or substitute the [0,60..359] range.
P.S. Is there a built-in function to convert degrees to radians and vice-versa? _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

I think I understand the reason why, but still I find it disturbing that in
this first expression, x has 6 elements:
Prelude> let x = [0,60..359]; y = [0,60..359] in (x, y, map degreesToRadians
y)
([0,60,120,180,240,300],[0.0,60.0,120.0,180.0,240.0,300.0,360.0],[0.0,1.0471975333333332,2.094395066
6666664,3.1415926,4.188790133333333,5.235987666666667,6.2831852])
But if I add a comparison to y, x now has 7 elements:
Prelude> let x = [0,60..359]; y = [0,60..359] in (x, y, map degreesToRadians
y, *x==y*)
([0.0,60.0,120.0,180.0,240.0,300.0,360.0],[0.0,60.0,120.0,180.0,240.0,300.0,360.0],[0.0,1.0471975333
333332,2.0943950666666664,3.1415926,4.188790133333333,5.235987666666667,6.2831852],True)
I. J. Kennedy
On Wed, Jun 17, 2009 at 4:55 PM, Alan Mock
That's because [0,60,..359] is not the same as [0,60..359] :: [Double]. So what you're passing to degreesToRadians is [0.0,60.0,120.0,180.0,240.0,300.0,360.0] and not [0,60,120,180,240,300]. I don't know why the Double version adds another number, though.
On Jun 17, 2009, at 4:35 PM, Aaron MacDonald wrote:
For some reason, the map function returns a list that has one more element
than my input list.
My input list is a range defined by [0, 60..359] (should translate into [0,60,120,180,240,300]).
The function I'm giving to map is defined this way: ----- degreesToRadians :: Double -> Double degreesToRadians degrees = degrees * (pi / 180) -----
This is how I'm calling map overall: -----
map degreesToRadians [0,60..359]
[0.0,1.0471975511965976,2.0943951023931953,3.141592653589793,4.1887902047863905,5.235987755982989,6.283185307179586] -----
As you can hopefully see, there are seven elements instead of six. Getting the length confirms this: -----
length [0,60..359] 6 length $ map degreesToRadians [0,60..359] 7
I do not seem to get this behaviour with the length if I either substitute the degreesToRadians function or substitute the [0,60..359] range.
P.S. Is there a built-in function to convert degrees to radians and vice-versa? _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Am Donnerstag 18 Juni 2009 15:24:20 schrieb Jack Kennedy:
I think I understand the reason why, but still I find it disturbing that in this first expression, x has 6 elements:
Prelude> let x = [0,60..359]; y = [0,60..359] in (x, y, map degreesToRadians y)
You give no type for x, so the default is chosen, that is Integer. The expression map degreesToRadians y forces y to have type [Double] (you could give y a more general type if you specified a type signature).
([0,60,120,180,240,300],[0.0,60.0,120.0,180.0,240.0,300.0,360.0],[0.0,1.047 1975333333332,2.094395066 6666664,3.1415926,4.188790133333333,5.235987666666667,6.2831852])
But if I add a comparison to y, x now has 7 elements:
Prelude> let x = [0,60..359]; y = [0,60..359] in (x, y, map degreesToRadians y, *x==y*) ([0.0,60.0,120.0,180.0,240.0,300.0,360.0],[0.0,60.0,120.0,180.0,240.0,300.0 ,360.0],[0.0,1.0471975333 333332,2.0943950666666664,3.1415926,4.188790133333333,5.235987666666667,6.2 831852],True)
Now, the expression x==y forces x to have the same type as y, which still is [Double]. But, lo and behold: Prelude> let degreesToRadians :: Double -> Double; degreesToRadians d = d*pi/180 Prelude> let x :: (Num a, Enum a) => [a]; x = [0, 60 .. 359]; y :: (Num a, Enum a) => [a]; y = [0, 60 .. 359] Prelude> (x,y,map degreesToRadians y, x == y) ([0,60,120,180,240,300],[0,60,120,180,240,300], [0.0,1.0471975511965976,2.0943951023931953,3.141592653589793,4.1887902047863905,5.235987755982989,6.283185307179586],True)
I. J. Kennedy

Check this out: Prelude> [0,60..330]::[Double] [0.0,60.0,120.0,180.0,240.0,300.0,360.0] Prelude> [0,60..329]::[Double] [0.0,60.0,120.0,180.0,240.0,300.0] It looks like the decision the step to the next value in case of flt. point enumeration depends on >= enumWith / 2. But that should be answered by those who know from under the hood. -- Met vriendelijke groet, =@@i

On Thu, Jun 18, 2009 at 05:32:26PM +0200, Aai wrote:
Check this out:
Prelude> [0,60..330]::[Double] [0.0,60.0,120.0,180.0,240.0,300.0,360.0]
Prelude> [0,60..329]::[Double] [0.0,60.0,120.0,180.0,240.0,300.0]
It looks like the decision the step to the next value in case of flt. point enumeration depends on >= enumWith / 2. But that should be answered by those who know from under the hood.
That is correct. The reason for this is because of the inaccuracy of floating point numbers. For example, consider [0.1,0.2..10.0] which clearly ought to contain 100 numbers, every tenth from 0.1 through 10.0 inclusive. But 0.1 cannot be represented exactly in binary, so adding 0.1 to itself 100 times might very well give a result like 10.0000000002. Should this be included in the range, or not? After all, it's bigger than 10.0...but it would be quite surprising if the 10.0000000002 were left out. Hence the last number is included even if it is up to 1/2 of a step over the end value of the range. But this can also be surprising at times (as the original poster found out!). What to do? The answer is: don't use list enumerations for floating point numbers!! It is nonsensical. Alternative options include: * use Rational instead of Double, which IS exact * use Integers for the enumeration, and then convert to Double and so on. -Brent

On Wed, 17 Jun 2009 23:35:23 +0200, Aaron MacDonald
This is how I'm calling map overall: -----
map degreesToRadians [0,60..359] [0.0,1.0471975511965976,2.0943951023931953,3.141592653589793,4.1887902047863905,5.235987755982989,6.283185307179586 ]
As you can hopefully see, there are seven elements instead of six. Getting the length confirms this: -----
length [0,60..359] 6 length $ map degreesToRadians [0,60..359] 7
Enumeration works differently for Double: Prelude> [0, 60..359 :: Double] [0.0,60.0,120.0,180.0,240.0,300.0,360.0] Prelude> length [0, 60..359 :: Double] 7 -- Met vriendelijke groet, Henk-Jan van Tuyl -- http://functor.bamikanarie.com http://Van.Tuyl.eu/ --

Sigh. Well, what I was trying to do was get all angles in the range [0, 360) that have 60 degrees between them, since I'm going to be working with hexagons. I figured I'd use a range instead of hard-coded angles in case I wanted to use other shapes. Thanks, Aaron On 17-Jun-09, at 6:58 PM, Henk-Jan van Tuyl wrote:
On Wed, 17 Jun 2009 23:35:23 +0200, Aaron MacDonald
wrote:
This is how I'm calling map overall: -----
map degreesToRadians [0,60..359] [0.0,1.0471975511965976,2.0943951023931953,3.141592653589793,4.1887902047863905,5.235987755982989,6.283185307179586 ]
As you can hopefully see, there are seven elements instead of six. Getting the length confirms this: -----
length [0,60..359] 6 length $ map degreesToRadians [0,60..359] 7
Enumeration works differently for Double: Prelude> [0, 60..359 :: Double] [0.0,60.0,120.0,180.0,240.0,300.0,360.0] Prelude> length [0, 60..359 :: Double] 7
-- Met vriendelijke groet, Henk-Jan van Tuyl

Aaron, Look at the following snippet:
length ([0,60..359] :: [Double]) 7
Basically, the Enum instance for Double is done differently than for Int (I
don't remember why exactly). If you take off the type signature, it uses Int
by default. When you use map, it implicitly converts that to a Double.
Hope that helps.
Michael
On Thu, Jun 18, 2009 at 12:35 AM, Aaron MacDonald
For some reason, the map function returns a list that has one more element than my input list.
My input list is a range defined by [0, 60..359] (should translate into [0,60,120,180,240,300]).
The function I'm giving to map is defined this way: ----- degreesToRadians :: Double -> Double degreesToRadians degrees = degrees * (pi / 180) -----
This is how I'm calling map overall: -----
map degreesToRadians [0,60..359]
[0.0,1.0471975511965976,2.0943951023931953,3.141592653589793,4.1887902047863905,5.235987755982989,6.283185307179586] -----
As you can hopefully see, there are seven elements instead of six. Getting the length confirms this: -----
length [0,60..359] 6 length $ map degreesToRadians [0,60..359] 7
I do not seem to get this behaviour with the length if I either substitute the degreesToRadians function or substitute the [0,60..359] range.
P.S. Is there a built-in function to convert degrees to radians and vice-versa? _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (8)
-
Aai
-
Aaron MacDonald
-
Alan Mock
-
Brent Yorgey
-
Daniel Fischer
-
Henk-Jan van Tuyl
-
Jack Kennedy
-
Michael Snoyman