Tôi đang phải vật lộn với sự hiểu biết về chức năng đơn vị trong JavaScript. Đặc biệt là vì điều khiến tôi 'có được' monads (hoặc ít nhất tôi nghĩ) là đối tượng Promise, và cách then
luôn trả về một Promise mới, bất kể chức năng nào bạn chuyển đến then
, theo kiến thức của tôi tương đương với bind
hoặc >>=
trong haskell. Điều này hoàn toàn có ý nghĩa đối với tôi, bởi vì nó đảm bảo rằng tất cả các chức năng của bạn được thực hiện trong 'vũ trụ đơn nguyên', để nói.JS Chức năng đơn vị đơn vị
Điều gì khiến tôi bận tâm là cuộc trò chuyện 'Monads và Gonads' của Douglas Crockford. Trong việc thực hiện của mình, bind
trả về trực tiếp kết quả của hàm chuyển đổi, mà không kiểm tra nếu kết quả đó là một đơn nguyên. Điều này đụng độ với phương thức then
của Promises, vì then
LUÔN trả về một Lời hứa mới.
Một ý nghĩ là phương pháp nâng. Việc thực hiện của anh ta đảm bảo rằng 'nâng' sẽ luôn trả lại một đơn nguyên, và có lẽ then
đã được nâng lên để Hứa hẹn. Tuy nhiên, điều này có nghĩa là then !== bind
và lời hứa đó có liên kết nội bộ ở đâu đó.
Trực giác của tôi là ít nhất phải có loại kiểm tra nào đó trong chức năng liên kết để kiểm tra kết quả của phép biến đổi và cho phép một kết quả được thông qua, nhưng sẽ chặn không phải monads và chuyển chúng qua đơn vị một lần nữa, như 'lift'.
* EDIT
Ngoài ra, tôi có ấn tượng rằng then
tương đương với bind, flatMap, >>=
bởi vì nó có khả năng unwrap monads khác, kể cả những người khác nhau và những kiểu riêng của nó. Trong khi xem xét một số tham chiếu lý thuyết danh mục trong JavaScript, flatMap
được sử dụng để ánh xạ trên một tập hợp các mảng lồng nhau và sau đó làm phẳng chúng theo một thứ nguyên. Điều này phù hợp với cách then
sẽ chờ các lời hứa khác mà bạn đưa ra. Nhưng dường như không phù hợp với thực hiện ban đầu được đề cập ở trên. Tôi cảm thấy lạc lõng.
Bất kỳ ai có nhiều kinh nghiệm về FP đều làm sáng tỏ những gì tôi đang bỏ lỡ hoặc tôi chỉ là quá tắt và cần phải bắt đầu lại từ đầu?
Một số ví dụ mã ...
// Crockford's 'bind'
monad.bind = function(transform) {
// value was passed in through the unit constructor
return transform(value);
}
khu vực rắc rối của tôi
// Set the 'isMonad' prop to be true, for all
// monads made with the MONAD macroid
monad.isMonad = true;
// shouldn't this ALWAYS return a monad?
monad.bind = function(transform) {
var res = transform(value);
return (res && res.isMonad) ? res : unit(res);
}
LƯU Ý Tôi biết tôi không sử dụng phiên bản chính thức thực hiện của mình trong đầy đủ, tôi chỉ tập trung vào phương pháp liên kết đặc biệt.
Việc thực hiện đầy đủ có thể được tìm thấy tại
https://github.com/douglascrockford/monad/blob/master/monad.js
Cập nhật
Sau khi thực hiện một số nghiên cứu nhiều hơn, >>=
không cần phải quay trở lại một trường hợp đơn nguyên. Nhận xét của Bergi làm sáng tỏ cách Promise.prototype.then
bị quá tải và hoạt động như một chức năng khác tùy thuộc vào những gì bạn giải quyết.
Ngoài ra, rất nhiều thứ bắt đầu nhấp vào khi tôi lùi lại một bước và xem cách Monads khác với các functors thông thường. Các chi tiết vẫn còn hơi mờ, nhưng tôi nghĩ tôi có được bức tranh lớn.
Một vài tài liệu tham khảo tốt đã giúp xóa các đám mây,
này ai khuyên cho một cái nhìn tổng quan cấp cao, nói cách con người
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
Đừng để những hình ảnh đánh lừa bạn, điều này giống như vàng cho tôi. Không phải trong JavaScript, nhưng vẫn rất thông tin về các khái niệm tổng thể.
Ngoài ra, hàng loạt YouTube này vào loại lý thuyết trong JavaScript
https://www.youtube.com/watch?v=-FkgOHvNAU8&list=PLwuUlC2HlHGe7vmItFmrdBLn6p0AS8ALX&index=1
loạt YouTube này gọi là 'Fun Fun Chức năng' là tuyệt vời, chủ nhà là một trong những giáo viên tốt nhất mà tôi đã tìm thấy trực tuyến. Video này giới thiệu về monads và được đề xuất bởi MrE
.
Rất khuyến khích !.
https://www.youtube.com/watch?v=9QveBbn7t_c&app=desktop
Hai tài liệu tham khảo đó đã làm tôi ngạc nhiên. Hy vọng rằng sẽ giúp tất cả mọi người khác là tốt.
Tôi thật sự khuyên bạn bỏ qua phần nói/mã Crockford này. Sự hiểu biết của bạn từ lời hứa là hợp lý. Bạn sẽ tìm thấy nó một chỉ báo * tốt * mà bạn thấy Crockford nói chuyện khó hiểu vì anh ta bối rối. –
'then' là một sự thực thi khủng khiếp của một đơn nguyên. Nó kết hợp 'bind' /' chain'/'flatMap'/bất cứ cái gì bạn gọi nó với một' map' bình thường, và nó cũng chấp nhận bất kỳ giá trị nào là giá trị trả về. Trong Haskell, bạn hoàn toàn không cần 'isMonad', bởi vì trình biên dịch đã kiểm tra xem hàm bạn truyền vào có kiểu trả về đúng hay không. – Bergi
Thêm một đề xuất khác cho "bỏ qua Crockford". – naomik