The list of map results is even longer.

in this Haskell example, the result is sometimes one more than the base list. Any clue for this?

Prelude> let x3 = [1,3..10] Prelude> x3 [1,3,5,7,9] Prelude> length x3 5 Prelude> length $ map (+1) x3 5 Prelude> length $ map (*3) x3 5 Prelude> length $ map (/2) x3 6 Prelude> length $ map (/1) x3 6 Prelude> length $ map (`div`1) x3 5 Prelude> map log x3 [0.0,1.0986122886681098,1.6094379124341003 ,1.9459101490553132,2.1972245773362196,2.3978952727983707] Prelude> length it 6 
+7
haskell
source share
1 answer

As @duplode shows, this is due to the way .. behaves with a floating point versus integers:

 Prelude> let x3 = [1,3..10] :: [Double] Prelude> length x3 6 Prelude> let x3 = [1,3..10] :: [Int] Prelude> length x3 5 

Update in response to comment ...

A definition like this in ghci:

 let xs = [1,3..11] 

is polymorphic. .. is a shortcut to the enumFromThenTo function:

 let xs = enumFromThenTo 1 3 11 

The result is polymorphic - the specified expression is of the type:

 ghci> :t xs x3 :: (Enum t, Num t) => [t] 

If you just print it, Haskell selects the type as [Integer] , and you get:

 [1,3,5,7,9] 

It uses an integer version of enumFromThenTo .

However, if you apply a floating point operation to a list, Haskell interprets it as [Double] , and then it becomes one item longer for the reasons described above:

 ghci> map (+ 0.0) x3 [1.0,3.0,5.0,7.0,9.0,11.0] -- length 6 now! 

Thus, the map operation "changes" the length of the list only because it changes the interpretation of its type, which modifies the enumFromThenTo function to create it.

Upshot: a list defined as [1,3..11] does not know the length until its type is determined.

+4
source share

All Articles