2011-07-24 35 views
19

Tôi rất mới với Haskell. Có thể ai đó vui lòng giải thích lý do tại sao việc xác định danh sách như thế này trả về danh sách rỗngPhạm vi giảm dần trong Haskell

ghci> let myList = [10..1] 
ghci> myList 
[] 

Tuy nhiên, công trình này hoạt động chính xác.

ghci> let myList = [10, 9..1] 
ghci> myList 
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 

Trả lời

34

Về cơ bản, bởi vì [10..1] được phiên dịch sang enumFromTo 10 1 mà chính nó có ngữ nghĩa để tạo ra một danh sách bằng cách lấy tất cả các yếu tố ít hơn 1 là kết quả của tính trở lên (với bước kích thước +1) từ (bao gồm) 10.

Trong khi [10, 9..1] được phiên dịch sang enumFromToThen 10 9 1 trong đó nêu rõ ràng đếm bước kích thước như 9-10, tức là -1 (đó là mã hóa cứng để +1 cho enumFromTo)

Một đặc điểm kỹ thuật chính xác hơn có thể được tìm thấy trong Báo cáo Haskell (6.3.4 các Enum class):

enumFrom  :: a -> [a]   -- [n..] 
enumFromThen :: a -> a -> [a]  -- [n,n'..] 
enumFromTo  :: a -> a -> [a]  -- [n..m] 
enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m] 

Đối với các loại IntInteger, các chức năng liệt kê hav e ý nghĩa sau:

  • Trình tự enumFrom e1 là danh sách [e1,e1+1,e1+2,...].

  • Trình tự enumFromThen e1 e2 là danh sách [e1,e1+i,e1+2i,...], trong đó tăng, i, là e2-e1. Số gia tăng có thể bằng 0 hoặc âm. Nếu số gia tăng bằng không, tất cả các phần tử danh sách đều giống nhau.

  • Trình tự enumFromTo e1 e3 là danh sách [e1,e1+1,e1+2,...e3]. Danh sách trống nếu e1 > e3.

  • Trình tự enumFromThenTo e1 e2 e3 là danh sách [e1,e1+i,e1+2i,...e3], trong đó số tăng, i, là e2-e1. Nếu số gia tăng dương hoặc bằng không, danh sách sẽ kết thúc khi phần tử tiếp theo sẽ lớn hơn e3; danh sách trống nếu e1 > e3. Nếu số gia tăng là số âm, danh sách sẽ kết thúc khi phần tử tiếp theo sẽ nhỏ hơn e3; danh sách trống nếu e1 < e3.

+0

Cảm ơn bạn, điều này có ý nghĩa. Thoạt nhìn tôi nghĩ đây là ký hiệu khá ngớ ngẩn nhưng tôi có thể thấy bây giờ nó có thể xác định kích thước của các bước trong phạm vi. Rất tuyệt! Rất vui mừng về Haskell bây giờ :) – Christopher

11

chuỗi số học ký hiệu chỉ là cú pháp đường cho các chức năng từ lớp Enum.

[a..]  = enumFrom a 
[a..b] = enumFromTo a b 
[a, b..] = enumFromThen a b 
[a, b..c] = enumFromThenTo a b c 

Đối với lý do tại sao họ đã không được định nghĩa để tự động đảo ngược, tôi chỉ có thể suy đoán nhưng đây là một số lý do có thể:

  • Nếu ab được định nghĩa ở đâu đó, nó sẽ là khó khăn hơn để nói trong nháy mắt mà theo đó hướng [a..b] sẽ đi.

  • Nó có các thuộc tính toán học đẹp hơn để giải thích.Bạn không phải thêm các trường hợp đặc biệt khi chuỗi bị đảo ngược.

2

Nếu bạn muốn tạo ra một danh sách a-b bất kể a < b, bạn có thể sử dụng như sau:

[a, a + (signum $ b - a)..b]

+1

Lưu ý rằng điều này tạo ra một danh sách vô hạn nếu 'a = b'. – hammar

+0

@hammar Tôi đã sửa chữa :) – dionyziz

Các vấn đề liên quan