Đi từng bước:
list2 = list of numbers
Chúng tôi sẽ thực hiện việc này là điều đương nhiên, vì vậy list2
vẫn chỉ là một danh sách các số.
for i from 0 to N // N being a positive integer
Các cách chính xác để làm điều này trong Haskell nói chung là với một danh sách. Laziness có nghĩa là các giá trị sẽ được tính toán chỉ khi được sử dụng, vì vậy việc duyệt qua một danh sách từ 0 đến N kết thúc bằng cùng một thứ với vòng lặp bạn có ở đây. Vì vậy, chỉ cần [0..n]
sẽ thực hiện thủ thuật; chúng ta chỉ cần tìm ra những gì cần làm với nó.
for each number in list2
Với "cho mỗi" chúng ta có thể suy ra rằng chúng tôi sẽ cần phải đi qua toàn bộ list2
đây; những gì chúng tôi làm với nó, chúng tôi chưa biết.
if number == i, add to list1
Chúng tôi đang xây dựng list1
khi chúng ta đi, vì vậy lý tưởng nhất chúng tôi muốn điều đó là kết quả cuối cùng của biểu thức. Điều đó cũng có nghĩa là ở mỗi bước đệ quy, chúng tôi muốn kết quả là list1
chúng tôi có "cho đến nay". Để làm điều đó, chúng tôi sẽ cần phải đảm bảo rằng chúng tôi vượt qua kết quả của mỗi bước khi chúng tôi đi.
Vì vậy, nhận được xuống để thịt của nó:
Chức năng filter
tìm tất cả các yếu tố trong một danh sách phù hợp với một số vị; chúng tôi sẽ sử dụng filter (== i) list2
tại đây để tìm những gì chúng tôi đang theo dõi, sau đó nối thêm vào kết quả của bước trước đó. Vì vậy, mỗi bước sẽ trông giống như sau:
step :: (Num a) => [a] -> a -> [a]
step list1 i = list1 ++ filter (== i) list2
Điều đó xử lý vòng lặp bên trong. Bước lùi ra phía sau, chúng ta cần phải chạy điều này cho mỗi giá trị i
từ danh sách [0..n]
, với giá trị list1
được truyền đi ở mỗi bước.Đây chính là điều gấp chức năng là cho, và trong trường hợp này step
là chính xác những gì chúng ta cần cho một lần trái:
list2 :: (Num a) => [a]
list2 = -- whatever goes here...
step :: (Num a) => [a] -> a -> [a]
step list1 i = list1 ++ filter (== i) list2
list1 :: (Num a) => a -> [a]
list1 n = foldl step [] [0..n]
Nếu bạn đang tự hỏi nơi đệ quy là, cả hai filter
và foldl
đang làm điều đó cho chúng ta . Theo quy tắc chung, tốt hơn là tránh đệ quy trực tiếp khi có các hàm cấp cao hơn để thực hiện điều đó cho bạn.
Điều đó nói rằng, thuật toán ở đây là ngớ ngẩn theo nhiều cách, nhưng tôi không muốn tham gia bởi vì nó có vẻ như nó sẽ phân tâm khỏi câu hỏi thực tế của bạn nhiều hơn nó sẽ giúp ích.
Tại sao không sử dụng 'concatMap' thay vì xếp chồng lên một bước nối rõ ràng? – bdonlan
Lưu ý rằng trong trường hợp này, bạn có thể sử dụng danh sách hiểu: [số | i <- [1..N], số <-list2, i == number] là bản dịch trực tiếp mã giả của bạn. – ysdx
Cảm ơn bạn đã có câu trả lời tuyệt vời. Tôi nhận ra rằng đoạn trích tôi đăng là kỳ lạ ... Tôi đã vứt bỏ bất kỳ ý nghĩa nào từ nó. Đó là một phần của bài tập sắp xếp radix tôi đang làm. –