Real World Haskell, chương 4, trang 98 của bản in hỏi liệu words
có thể được thực hiện bằng cách sử dụng các nếp gấp không và đây cũng là câu hỏi của tôi:
Có thể không? Nếu không, tại sao? Nếu là nó, làm thế nào?
Tôi đã đưa ra những điều sau, dựa trên ý tưởng rằng mỗi phi không gian nên được thêm vào từ cuối cùng trong danh sách đầu ra (điều này xảy ra trong phần otherwise
bảo vệ) và rằng một khoảng trắng sẽ kích hoạt việc nối thêm một từ emtpy vào danh sách đầu ra nếu chưa có danh sách này (điều này được xử lý trong if
- then
- else
).
myWords :: String -> [String]
myWords = foldr step [[]]
where
step x yss@(y:ys)
| x == ' ' = if y == "" then yss else "":yss
| otherwise = (x:y):ys
Rõ ràng giải pháp này là sai, vì các khoảng trắng hàng đầu trong chuỗi đầu vào dẫn đến một chuỗi trống hàng đầu trong danh sách chuỗi đầu ra.
Ở liên kết trên, tôi đã xem xét một số giải pháp được đề xuất cho các độc giả khác và nhiều giải pháp trong số đó hoạt động tương tự như giải pháp của tôi, nhưng họ thường "xử lý hậu kỳ" đầu ra của nếp gấp, ví dụ như bằng cách sử dụng tail
nó nếu có là một chuỗi hàng đầu trống.
Các cách tiếp cận khác sử dụng các bộ dữ liệu (thực tế chỉ là các cặp), do đó, giao dịch gấp với cặp và có thể xử lý tốt các khoảng trắng ở đầu / cuối.
Trong tất cả các cách tiếp cận này, foldr
(hoặc một nếp gấp khác, fwiw) không phải là chức năng cung cấp đầu ra cuối cùng ra khỏi hộp; luôn luôn có một cái gì đó khác phải điều chỉnh đầu ra bằng cách nào đó.
Do đó, tôi quay trở lại câu hỏi ban đầu và hỏi liệu thực tế có thể thực hiện được không words
(theo cách nó xử lý chính xác các dấu cách / hàng đầu / lặp lại) bằng cách sử dụng các nếp gấp. Bằng cách sử dụng các nếp gấp, ý tôi là chức năng gấp phải là chức năng ngoài cùng:
myWords :: String -> [String]
myWords input = foldr step seed input