Sự cần thiết của ứng dụng tinh khiết


19

Tôi đang học Ứng dụng của Haskell. Dường như với tôi (có lẽ tôi đã sai) rằng purechức năng này không thực sự cần thiết, ví dụ:

pure (+) <*> [1,2,3] <*> [3,4,5]

có thể được viết như

(+) <$> [1,2,3] <*> [3,4,5]

Ai đó có thể giải thích lợi ích mà purehàm cung cấp qua ánh xạ rõ ràng fmapkhông?


1
Bạn đúng - pure f <*> xhoàn toàn giống như fmap f x. Tôi chắc chắn rằng có một số lý do tại sao puređược đưa vào Applicative, nhưng tôi không hoàn toàn chắc chắn tại sao.
bradrn

4
Tôi không có thời gian cho câu trả lời, và dù không tin rằng điều này sẽ tạo ra một câu trả lời hay hoặc hoàn chỉnh, nhưng một quan sát: purecho phép người ta sử dụng các giá trị "thuần túy" trong tính toán Áp dụng. Trong khi, như bạn quan sát chính xác, pure f <*> xcũng giống như f <$> x, không có tương đương như vậy cho, nói , f <*> x <*> pure y <*> z. (Ít nhất là tôi không nghĩ vậy.)
Robin Zigmond

3
Như một lý do khác, lý thuyết hơn, biện minh - có một công thức thay thế liên quan chặt chẽ với Monoidlớp quan trọng - trong đó puretương ứng với Monoidyếu tố nhận dạng. (Điều này cho thấy Applicativekhông purecó thể là thú vị, vì Semigroup- đó là một Monoidmà không nhất thiết phải có một bản sắc -. Vẫn được sử dụng thực tế, bây giờ tôi nghĩ về nó, tôi dường như nhớ lại PureScript có chính xác như một "applicative mà không pure" lớp, mặc dù tôi don 'không biết nó dùng để làm gì.)
Robin Zigmond

2
@RobinZigmond fmap (\f' x' z' -> f' x' y z') f <*> x <*> z, tôi nghĩ vậy. Ý tưởng là trong Applicativetài liệu như luật "trao đổi".
HTNW

3
@RobinZigmond Applicativemà không puretồn tại như Applytừ semigroupoids .
song mã

Câu trả lời:


8

Tôi đang ở bên cạnh năng lực của mình ở đây, vì vậy đừng lấy cái này nhiều hơn nó, nhưng nó quá dài để nhận xét.

Có thể có những lý do thực tế để đưa purevào lớp loại, nhưng nhiều tóm tắt Haskell có nguồn gốc từ nền tảng lý thuyết, và tôi tin rằng đó cũng là trường hợp Applicative. Như tài liệu nói, đó là một functor đơn hình lỏng lẻo mạnh mẽ (xem https://cstheory.stackexchange.com/q/12412/56098 để biết thêm chi tiết). Tôi cho rằng điều đó puređóng vai trò là danh tính , giống như returnđối với Monad(đó là một monoid trong danh mục endofunctor ).

Xem xét pureliftA2:

pure :: a -> f a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c

Nếu bạn nheo mắt một chút, bạn có thể tưởng tượng đó liftA2là một hoạt động nhị phân, đó cũng là những gì tài liệu nêu:

Nâng một hàm nhị phân thành hành động.

pure, sau đó, là danh tính tương ứng.


6
Chính xác. Applicativekhông có puresẽ là một functor nửa , nửa nhóm thay vì một đơn vị.
rẽ trái

20

fmapkhông phải lúc nào cũng cắt nó. Cụ thể, purelà những gì cho phép bạn giới thiệu f(nơi fApplicative) khi bạn chưa có nó. Một ví dụ điển hình là

sequence :: Applicative f => [f a] -> f [a]

Nó lấy một danh sách "hành động" tạo ra các giá trị và biến nó thành một hành động tạo ra một danh sách các giá trị. Điều gì xảy ra khi không có hành động trong danh sách? Kết quả lành mạnh duy nhất là một hành động không tạo ra giá trị:

sequence [] = pure [] -- no way to express this with an fmap
-- for completeness
sequence ((:) x xs) = (:) <$> x <*> sequence xs

Nếu bạn không có pure, bạn sẽ bị buộc phải yêu cầu một danh sách hành động không trống. Bạn chắc chắn có thể làm cho nó hoạt động, nhưng nó giống như nói về phép cộng mà không đề cập đến 0 hoặc phép nhân mà không có 1 (như những người khác đã nói, vì Applicatives là đơn hình). Bạn sẽ liên tục gặp phải các trường hợp cạnh có thể dễ dàng giải quyết purenhưng thay vào đó phải được giải quyết bằng các hạn chế kỳ lạ đối với đầu vào và các thiết bị hỗ trợ băng tần khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.