Chìa khóa để hiểu functors applicative là để tìm ra cấu trúc mà họ bảo tồn.
Thường xuyên functors bảo tồn cấu trúc phân loại cơ bản: họ ánh xạ các đối tượng và morphisms giữa các loại, và họ bảo tồn pháp luật của thể loại (associativity và bản sắc).
Nhưng danh mục có thể có cấu trúc nhiều hơn. Ví dụ, nó có thể cho phép định nghĩa các ánh xạ giống như hình thái nhưng lấy nhiều đối số. Ánh xạ như vậy được xác định bằng cách nghiền: ví dụ: hàm của hai đối số được định nghĩa là hàm của một đối số trả về một hàm khác. Điều này là có thể nếu bạn có thể xác định một đối tượng đại diện cho một loại hàm. Nói chung, đối tượng này được gọi là số mũ (trong Haskell, nó chỉ là loại b->c
). Sau đó chúng ta có thể có hình thái từ một đối tượng đến một hàm mũ và gọi nó là một hình thái hai đối số.
Định nghĩa truyền thống của một hàm functor ứng dụng trong Haskell dựa trên ý tưởng về các hàm ánh xạ của nhiều đối số. Nhưng có một định nghĩa tương đương chia tách hàm đa đối số dọc theo một ranh giới khác. Bạn có thể xem một hàm như một ánh xạ của sản phẩm (một cặp, trong Haskell) sang một loại khác (ở đây, c
).
a -> (b -> c) ~ (a, b) -> c
Điều đó cho phép chúng ta nhìn vào functors applicative như functors mà giữ gìn sản phẩm. Nhưng một sản phẩm chỉ là một ví dụ về cái được gọi là cấu trúc đơn hình.
Nói chung, danh mục monoidal là một danh mục được trang bị một sản phẩm tensor và một đối tượng đơn vị. Trong Haskell, ví dụ, sản phẩm cartesian (một cặp) và loại đơn vị ()
. Tuy nhiên, lưu ý rằng các quy luật đơn trị (luật kết hợp và luật đơn vị) chỉ có giá trị lên đến một đẳng cấu. Ví dụ:
(a,()) ~ a
Một hàm functor sau đó có thể được định nghĩa là một hàm duy trì cấu trúc monoidal. Đặc biệt, cần bảo quản thiết bị và sản phẩm. Nó không quan trọng cho dù chúng ta làm "nhân" trước hoặc sau khi áp dụng functor. Các kết quả nên là đẳng cấu.
Tuy nhiên, chúng tôi không thực sự cần một hàm foidtor toàn diện. Tất cả những gì chúng ta cần là hai hình thái (trái ngược với đẳng cấu) - một cho phép nhân và một cho đơn vị. Một functor như vậy mà một nửa bảo tồn cấu trúc đơn hình được gọi là lax monoidal functor. Do đó định nghĩa khác:
class Functor f => Monoidal f where
unit :: f()
(**) :: f a -> f b -> f (a, b)
Thật dễ dàng để chứng minh rằng Monoidal
tương đương với Applicative
. Ví dụ, chúng ta có thể có được pure
từ unit
và ngược lại:
pure x = fmap (const x) unit
unit = pure()
Luật applicative làm theo cách đơn giản từ việc bảo tồn luật monoid (associativity và đơn vị pháp luật).
Về lý thuyết thể loại, bảo quản cấu trúc monoidal có liên quan đến sức mạnh tensorial, vì vậy một functor applicative cũng được biết đến như một mạnh lỏng lẻo functor monoidal. Tuy nhiên, trong Hask, mỗi functor có sức mạnh kinh điển đối với sản phẩm, do đó, thuộc tính này không thêm bất kỳ điều gì vào định nghĩa.
Bây giờ, nếu bạn đã quen thuộc với định nghĩa của một đơn nguyên như một monoid trong danh mục của endofunctors, bạn có thể quan tâm để biết rằng các ứng dụng tương tự, monoids trong thể loại endofunctors nơi sản phẩm tensor là Ngày convolution. Nhưng đó là khó khăn hơn nhiều để giải thích.
http://cstheory.stackexchange.com/questions/12412/explaining-applicative-functor-in-categorical-terms-monoidal-functors –