Tôi nghĩ rằng bạn đã cạn kiệt tất cả các khả năng thú vị. Bất kỳ Monad m => m a -> m achức năng nào chúng tôi có thể xác định sẽ trông giống như thế này:
e :: forall m a. Monad m => m a -> m a
e u = u >>= k
where
k :: a -> m a
k = _
Đặc biệt, nếu k = return, e = id. Để ekhông tồn tại id, kphải sử dụng u theo cách không cần thiết (ví dụ: k = const uvà k = flip fmap u . constsố tiền cho hai lần thử của bạn). Tuy nhiên, trong trường hợp như vậy, các uhiệu ứng sẽ được nhân đôi, dẫn eđến thất bại trong việc biến thành một hình thái đơn nguyên cho một số lựa chọn của đơn nguyên m. Điều đó là như vậy, hình thái đơn nguyên duy nhất đa hình trong đơn nguyên là id.
Hãy làm cho lập luận rõ ràng hơn.
Để rõ ràng, tôi sẽ chuyển sang join/ return/ fmapthuyết trình một lát. Chúng tôi muốn thực hiện:
e :: forall m a. Monad m => m a -> m a
e u = _
Những gì chúng ta có thể điền vào phía bên tay phải với? Lựa chọn rõ ràng nhất là u. Chính nó, điều đó có nghĩa là e = id, điều đó không có vẻ thú vị. Tuy nhiên, vì chúng ta cũng có join, returnvà fmap, có tùy chọn suy luận theo quy nạp, unhư trường hợp cơ sở. Nói rằng chúng tôi có một số v :: m a, được xây dựng bằng cách sử dụng các phương tiện chúng tôi có trong tay. Ngoài vra, chúng ta có các khả năng sau:
join (return v), đó là vvà do đó không cho chúng ta biết bất cứ điều gì mới;
join (fmap return v), đó là vtốt; và
join (fmap (\x -> fmap (f x) w) v), đối với một số khác w :: m ađược xây dựng theo quy tắc của chúng tôi, và một số f :: a -> a -> a. (Thêm mlớp để các loại f, như trong a -> a -> m a, và thêm joins để loại bỏ chúng sẽ không dẫn bất cứ nơi nào, như sau đó chúng ta sẽ phải thể hiện xuất xứ của những lớp, và điều cuối cùng sẽ làm giảm các trường hợp khác).
Trường hợp thú vị duy nhất là # 3. Tại thời điểm này, tôi sẽ đi một lối tắt:
join (fmap (\x -> fmap (f x) w) v)
= v >>= \x -> fmap (f x) w
= f <$> v <*> w
Bất kỳ phi uphía bên tay phải, do đó, có thể được thể hiện dưới dạng f <$> v <*> w, với vvà wlà một trong hai uhoặc lặp đi lặp lại hơn nữa của mô hình này, cuối cùng đạt us ở lá. Tuy nhiên, các biểu thức áp dụng của loại này có dạng chính tắc, có được bằng cách sử dụng các luật áp dụng để liên kết lại tất cả các cách sử dụng (<*>)bên trái, trong trường hợp này phải như thế này ...
c <$> u <*> ... <*> u
... Với dấu chấm lửng đứng ở vị trí 0 hoặc nhiều lần xuất hiện khác của khoảng ucách <*>và clà một a -> ... -> a -> achức năng của sự tự nhiên thích hợp. Do alà đa hình hoàn toàn, cnên, theo tham số, phải là một consthàm giống như một số đối số chọn một trong các đối số của nó. Điều đó là như vậy, bất kỳ biểu hiện như vậy có thể được viết lại về (<*)và (*>)...
u *> ... <* u
... Với dấu chấm lửng đứng bằng 0 hoặc nhiều lần xuất hiện ucách nhau bởi một trong hai *>hoặc <*, không có *>bên phải của a <*.
Quay trở lại bắt đầu, tất cả các idtriển khai không phải là ứng cử viên phải trông như thế này:
e u = u *> ... <* u
Chúng tôi cũng muốn etrở thành một hình thái đơn nguyên. Kết quả là, nó cũng phải là một hình thái ứng dụng. Đặc biệt:
-- (*>) = (>>) = \u v -> u >>= \_ -> v
e (u *> v) = e u *> e v
Đó là:
(u *> v) *> ... <* (u >* v) = (u *> ... <* u) *> (v *> ... <* v)
Bây giờ chúng ta có một con đường rõ ràng hướng tới một ví dụ mẫu. Nếu chúng ta sử dụng các luật áp dụng để chuyển đổi cả hai mặt sang dạng chính tắc, chúng ta sẽ (vẫn) kết thúc với các us và s xen kẽ vở phía bên trái và với tất cả các vs sau tất cả các us ở phía bên tay phải. Điều đó có nghĩa là tài sản sẽ không giữ cho các đơn vị như IO, Statehoặc Writer, bất kể có bao nhiêu (*>)và (<*)có e, hoặc chính xác giá trị nào được chọn bởi các consthàm giống như ở hai bên. Một bản demo nhanh:
GHCi> e u = u *> u <* u -- Canonical form: const const <$> u <*> u <*> u
GHCi> e (print 1 *> print 2)
1
2
1
2
1
2
GHCi> e (print 1) *> e (print 2)
1
1
1
2
2
2
usẽ nhất thiết phải được nhân đôi trừ khie = id? (Chúng tôi cũng có thể viếte u = do _ <- u; _ <- u; _ <- u; uvà kết hợp thêmu-effects.) Làm thế nào chúng ta có thể mô tả toán học rằng "một giá trị monadicp :: m acó nhiều hiệu ứng sao chép từu :: m a? Và sau đó, làm thế nào chúng ta có thể chứng minh rằng nhân đôi (triplicated, vv)u-effects nhất thiết dẫn đến hành vi vi phạm luật hình thái đơn nguyên?