Như @duplode gợi ý, nó đã làm với cách cư xử với ..
nổi integers điểm vs:
Prelude> let x3 = [1,3..10] :: [Double]
Prelude> length x3
6
Prelude> let x3 = [1,3..10] :: [Int]
Prelude> length x3
5
Cập nhật để đáp ứng với những nhận xét ...
Một định nghĩa như điều này trong ghci:
let xs = [1,3..11]
là đa hình. Các ..
là một phím tắt cho enumFromThenTo
chức năng:
let xs = enumFromThenTo 1 3 11
Kết quả là đa hình - biểu thức trên có kiểu:
ghci> :t xs
x3 :: (Enum t, Num t) => [t]
Nếu bạn chỉ cần in ra, Haskell chọn để gõ là như [Integer]
, và bạn nhận được:
[1,3,5,7,9]
Ở đây, phiên bản số nguyên enumFromThenTo
đang được sử dụng.
Tuy nhiên, nếu bạn áp dụng một hoạt động điểm nổi vào danh sách, Haskell diễn giải nó như [Double]
, và sau đó nó trở thành một yếu tố còn vì những lý do giải thích ở trên:
ghci> map (+ 0.0) x3
[1.0,3.0,5.0,7.0,9.0,11.0] -- length 6 now!
Vì vậy, các map
hoạt động "thay đổi" độ dài của danh sách chỉ vì nó thay đổi cách diễn giải của loại của nó mà thay đổi mà chức năng enumFromThenTo
được gọi là để xây dựng nó.
Ảnh chụp nhanh: Danh sách được xác định là [1,3..11]
không có độ dài đã biết cho đến khi loại được xác định.
Điều này phải do các danh sách '..' được xác định rõ ràng và cách hoạt động kỳ lạ với các số dấu phẩy động. Xem [Phạm vi Haskell và phao nổi] (http://stackoverflow.com/q/7290438/2751851). – duplode
'[1,3..10]' là một ý tưởng tồi, đặc biệt là sử dụng các số dấu phẩy động. Sử dụng '[1,3..9]' thay thế, hoặc '[1,3..11]'. Số '10' rơi chính xác ở giữa" bước "cuối cùng (từ 9 đến 11), do đó làm tròn sẽ quyết định liệu xấp xỉ gần nhất với 10 là 9 hay 11. – chi
@chi, theo ý kiến của tôi, sai chỗ. Các số phân số (và * đặc biệt là * các biểu diễn điểm động) không có doanh nghiệp nào trong lớp 'Enum'. Cách sane để có được một danh sách các float như thế này là 'map fromIntegral [1,3..whatever]'. – dfeuer