Những câu trả lời khác ở đây là chính xác, nhưng tôi tự hỏi, nếu họ không hoàn toàn những gì bạn cần ... Tôi sẽ cố gắng để giữ này là đơn giản càng tốt, chỉ cần hai điểm:
Điểm 1. return
không phải là điều đặc biệt bằng ngôn ngữ Haskell. Nó không phải là một từ khóa, và nó không phải là cú pháp đường cho cái gì khác. Nó chỉ là một chức năng mà là một phần của typeclass Monad
. Chữ ký của nó chỉ đơn giản là:
return :: a -> m a
trong đó m
là chúng tôi đang nói đến cái nào vào lúc đó. Nó có một giá trị "tinh khiết" và mứt nó vào monad của bạn. (! Ngẫu nhiên, có một chức năng gọi là pure
đó là cơ bản là một từ đồng nghĩa với return
... tôi thích nó tốt hơn bởi vì tên của nó là rõ ràng hơn) Dù sao, nếu m
là danh sách đơn nguyên, sau đó return
có kiểu này:
return :: a -> [a]
Nếu nó giúp, bạn có thể nghĩ về loại đồng nghĩa type List a = [a]
, có thể làm cho nó rõ ràng hơn một chút rằng List
là thứ chúng ta đang thay thế cho m
. Dù sao, nếu bạn đang đi để thực hiện return
mình, cách hợp lý duy nhất mà bạn muốn thực hiện nó là bằng cách tham gia một số giá trị (của bất cứ loại a
) và gắn bó nó trong một danh sách bằng cách riêng của mình:
return a = [a]
Vì vậy, tôi có thể nói return 1
trong danh sách đơn lẻ và tôi sẽ nhận được [1]
. Tôi cũng có thể nói return [1, 2, 3]
và tôi sẽ nhận được [[1, 2, 3]]
.
Điểm 2.IO
là một đơn nguyên, nhưng không phải tất cả các mon đều là IO
. Nhiều hướng dẫn Haskell dường như liên kết hai chủ đề chủ yếu vì lý do lịch sử (tình cờ, cùng một lý do gây nhầm lẫn lịch sử dẫn đến return
quá kém tên). Có vẻ như bạn có thể có một số sự nhầm lẫn (dễ hiểu) xung quanh điều đó.
Trong mã của bạn, bạn đang trong danh sách đơn lẻ vì bạn đã viết do x <- [1, 2]
. Thay vào đó, nếu bạn đã viết do x <- getLine
, bạn sẽ ở trong đơn vị IO
(vì getLine
trả lại IO String
). Dù sao, bạn đang ở trong danh sách đơn nguyên, vì vậy bạn sẽ có được định nghĩa của danh sách là return
được mô tả ở trên. Bạn cũng có thể định nghĩa danh sách của >>=
, mà chỉ là (một phiên bản lật của) concatMap
, định nghĩa là:
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f xs = concat (map f xs)
Các khác được đăng câu trả lời khá nhiều có nó bao phủ từ đây :) Tôi biết tôi không trả lời của bạn câu hỏi trực tiếp, nhưng tôi hy vọng hai điểm này thay vì giải quyết những điều cơ bản mà bạn có thể đã thấy khó hiểu.
Ngoài những câu trả lời xuất sắc, tôi muốn chỉ ra rằng bạn không phải nhầm lẫn 'return' trong lớp 'Monad' với từ khóa' return' trong các ngôn ngữ mệnh lệnh giống như C. Chúng hoàn toàn khác nhau, nhưng khá nhiều người dùng ngôn ngữ đó thấy 'return' và không nhận ra rằng nó không gây ra giá trị trả về, nó tạo ra một tính toán sẽ trả về giá trị đó khi được đánh giá tại một số điểm sau đó. Là một ngôn ngữ chức năng, Haskell không cần bất cứ thứ gì giống như câu lệnh 'return'. –
Thật vậy, sự lựa chọn của Haskell để sử dụng từ 'return' là, imho, một sai lầm lớn. Nhưng do khả năng tương thích ngược, hiện tại không có quay trở lại! –
@DanBurton: bạn luôn có thể tạo bí danh :) 'do_not_return a = return a' –