2016-01-26 15 views
18

tôi đã có thể lập bản đồ định nghĩa functor của từ lý thuyết loại để định nghĩa Haskell trong các cách sau: kể từ khi đối tượng của Hask nhiều loại, các functor FĐịnh nghĩa Functor áp dụng từ lý thuyết danh mục POV là gì?

  • bản đồ tất cả các loại a của Hask để loại mới F a bằng, xấp xỉ nói rằng, hãy thêm "F" vào nó.
  • ánh xạ mọi hình thái a -> b của Hask vào hình thái mới F a -> F b sử dụng fmap :: (a -> b) -> (f a -> f b).

Cho đến giờ, rất tốt. Bây giờ tôi nhận được Applicative, và không thể tìm thấy bất kỳ đề cập đến một khái niệm như vậy trong sách giáo khoa. Bằng cách xem những gì nó thêm vào Functor, ap :: f (a -> b) -> f a -> f b, tôi đã cố gắng đưa ra định nghĩa của riêng mình.

Trước tiên, tôi nhận thấy rằng kể từ khi (->) cũng là một loại, hình thái của Hask cũng là đối tượng của nó. Trong ánh sáng này, tôi đã đưa ra một gợi ý rằng functor applicative là một functor cũng có thể ánh xạ "arrow" -objects của thể loại nguồn thành hình thái của một đích.

Đây có phải là trực giác thích hợp không? Bạn có thể cung cấp một định nghĩa chính thức và nghiêm ngặt hơn không?

+1

http://cstheory.stackexchange.com/questions/12412/explaining-applicative-functor-in-categorical-terms-monoidal-functors –

Trả lời

25

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.

+0

Công cụ "sức mạnh" này là gì? – dfeuer

+0

Có, nếu bạn có thể thêm một chút về "sức mạnh" có nghĩa là ở đây nó sẽ được làm rõ; đặc biệt là kể từ khi câu trả lời của leftaroundabout liên kết đến https://en.wikipedia.org/wiki/Monoidal_functor xuất hiện để xác định "functors monoidal mạnh" có nghĩa là "functor monoidal với một số ràng buộc giả định" và "faxtors monoidal lax" có nghĩa là "không có giả định bổ sung ", do đó, trong thuật ngữ đó" mạnh mẽ lax monoidal functor "dường như không có ý nghĩa. – Ben

+5

Cá nhân tôi thích nghĩ về các functors ứng dụng như 'functors khép kín' hơn là những người đơn hình. Thực tế là chúng là đơn thể ít nhiều trùng hợp, và buộc phải bảo toàn các số mũ, đó là lý do tại sao mã hóa 'Monoidal' của những thứ cảm thấy lộn xộn, trong khi '(<*>) :: f (a -> b) - > fa -> fb' combinator mà chúng ta sử dụng chính xác là việc lập bản đồ số mũ! Một cách khác để suy nghĩ về một ứng dụng là một đối tượng monoid liên quan đến (covariant) ngày convolution.Khung nhìn đó có lợi ích là nó chiếu sáng đường dẫn để tìm ra một dạng contravariant của Applicative. –

11

Bạn nói đúng, Applicative dịch ít đơn giản hơn Functor hoặc Monad. Nhưng về bản chất, nó là lớp của monoidal functors:

class Functor f => Monoidal f where 
    pureUnit :: f() 
    fzip :: f a -> f b -> f (a,b) 

Từ đó bạn có thể xác định – trong Hask

pure x = fmap (const x) pureUnit 

fs <*> xs = fmap (uncurry ($)) $ fzip fs xs 
Các vấn đề liên quan